---------------------------------------------------------------------- PHP Manual by: Mehdi Achour Friedhelm Betz Antony Dovgal Nuno Lopes Hannes Magnusson Georg Richter Damien Seguy Jakub Vrana And several others 2011-07-15 Edited By: Philip Olson (c) 1997-2011 the PHP Documentation Group ---------------------------------------------------------------------- Copyright Copyright (c) 1997 - 2011 by the PHP Documentation Group. This material may be distributed only subject to the terms and conditions set forth in the Creative Commons Attribution 3.0 License or later. A copy of the Creative Commons Attribution 3.0 license is distributed with this manual. The latest version is presently available at >> http://creativecommons.org/licenses/by/3.0/. If you are interested in redistribution or republishing of this document in whole or in part, either modified or unmodified, and you have questions, please contact the Copyright holders at >> doc-license@lists.php.net. Note that this address is mapped to a publicly archived mailing list. ---------------------------------------------------------------------- ---------------------------------------------------------------------- PHP Manual ---------------------------------------------------------------------- Preface PHP, which stands for "PHP: Hypertext Preprocessor" is a widely-used Open Source general-purpose scripting language that is especially suited for Web development and can be embedded into HTML. Its syntax draws upon C, Java, and Perl, and is easy to learn. The main goal of the language is to allow web developers to write dynamically generated web pages quickly, but you can do much more with PHP. This manual consists primarily of a function reference, but also contains a language reference, explanations of some of PHP's major features, and other supplemental information. You can download this manual in several formats at >> http://www.php.net/download-docs.php. More information about how this manual is developed can be found in the 'About the manual' appendix. If you are interested in the history of PHP, visit the relevant appendix. Authors and Contributors We highlight the currently most active people on front page of the manual, but there are many more contributors who currently help in our work or have provided a great amount of help to the project in the past. There are a lot of unnamed people who help out with user notes on manual pages, which continually get included in the references, the work of whom we are also very thankful for. All of the lists provided below are in alphabetical order. Authors and Editors The following contributors should be recognized for the impact they have made and/or continue to make by adding content to the manual: Bill Abt, Jouni Ahto, Alexander Aulbach, Daniel Beckham, Stig Bakken, Nilgu:n Belma Bugu:ner, Jesus M. Castagnetto, Ron Chmara, Sean Coates, John Coggeshall, Simone Cortesi, Peter Cowburn, Daniel Egeberg, Markus Fischer, Wez Furlong, Sara Golemon, Rui Hirokawa, Brad House, Pierre-Alain Joye, Etienne Kneuss, Moriyoshi Koizumi, Rasmus Lerdorf, Andrew Lindeman, Stanislav Malyshev, Rafael Martinez, Rick McGuire, Moacir de Oliveira Miranda Junior, Kalle Sommer Nielsen, Yasuo Ohgaki, Richard Quadling, Derick Rethans, Rob Richards, Sander Roobol, Egon Schmid, Thomas Schoefbeck, Sascha Schumann, Dan Scott, Masahiro Takagi, Yannick Torres, Michael Wallner, Lars Torben Wilson, Jim Winstead, Jeroen van Wolffelaar and Andrei Zmievski. The following contributors have done significant work editing the manual: Stig Bakken, Gabor Hojtsy, Hartmut Holzgraefe and Egon Schmid. User Note Maintainers The currently most active maintainers are: Daniel Brown, Nuno Lopes, Felipe Pena, Thiago Pojda and Maciek Sokolewicz. These people have also put a lot of effort into managing user notes: Mehdi Achour, Daniel Beckham, Friedhelm Betz, Victor Boivie, Jesus M. Castagnetto, Nicolas Chaillan, Ron Chmara, Sean Coates, James Cox, Vincent Gevers, Sara Golemon, Zak Greant, Szabolcs Heilig, Oliver Hinckel, Hartmut Holzgraefe, Etienne Kneuss, Rasmus Lerdorf, Matthew Li, Andrew Lindeman, Aidan Lister, Hannes Magnusson, Maxim Maletsky, Bobby Matthis, James Moore, Philip Olson, Sebastian Picklum, Derick Rethans, Sander Roobol, Damien Seguy, Jason Sheets, Tom Sommer, Jani Taskinen, Yasuo Ohgaki, Jakub Vrana, Lars Torben Wilson, Jim Winstead, Jared Wyles and Jeroen van Wolffelaar. ---------------------------------------------------------------------- * Preface ---------------------------------------------------------------------- ---------------------------------------------------------------------- Getting Started ---------------------------------------------------------------------- Introduction Table of Contents * What is PHP? * What can PHP do? ---------------------------------------------------------------------- What is PHP? PHP (recursive acronym for PHP: Hypertext Preprocessor) is a widely-used open source general-purpose scripting language that is especially suited for web development and can be embedded into HTML. Nice, but what does that mean? An example: Example #1 An introductory example Example Instead of lots of commands to output HTML (as seen in C or Perl), PHP pages contain HTML with embedded code that does "something" (in this case, output "Hi, I'm a PHP script!"). The PHP code is enclosed in special start and end processing instructions that allow you to jump into and out of "PHP mode." What distinguishes PHP from something like client-side JavaScript is that the code is executed on the server, generating HTML which is then sent to the client. The client would receive the results of running that script, but would not know what the underlying code was. You can even configure your web server to process all your HTML files with PHP, and then there's really no way that users can tell what you have up your sleeve. The best things in using PHP are that it is extremely simple for a newcomer, but offers many advanced features for a professional programmer. Don't be afraid reading the long list of PHP's features. You can jump in, in a short time, and start writing simple scripts in a few hours. Although PHP's development is focused on server-side scripting, you can do much more with it. Read on, and see more in the What can PHP do? section, or go right to the introductory tutorial if you are only interested in web programming. ---------------------------------------------------------------------- ---------------------------------------------------------------------- What can PHP do? Anything. PHP is mainly focused on server-side scripting, so you can do anything any other CGI program can do, such as collect form data, generate dynamic page content, or send and receive cookies. But PHP can do much more. There are three main areas where PHP scripts are used. * Server-side scripting. This is the most traditional and main target field for PHP. You need three things to make this work. The PHP parser (CGI or server module), a web server and a web browser. You need to run the web server, with a connected PHP installation. You can access the PHP program output with a web browser, viewing the PHP page through the server. All these can run on your home machine if you are just experimenting with PHP programming. See the installation instructions section for more information. * Command line scripting. You can make a PHP script to run it without any server or browser. You only need the PHP parser to use it this way. This type of usage is ideal for scripts regularly executed using cron (on *nix or Linux) or Task Scheduler (on Windows). These scripts can also be used for simple text processing tasks. See the section about Command line usage of PHP for more information. * Writing desktop applications. PHP is probably not the very best language to create a desktop application with a graphical user interface, but if you know PHP very well, and would like to use some advanced PHP features in your client-side applications you can also use PHP-GTK to write such programs. You also have the ability to write cross-platform applications this way. PHP-GTK is an extension to PHP, not available in the main distribution. If you are interested in PHP-GTK, visit >> its own website. PHP can be used on all major operating systems, including Linux, many Unix variants (including HP-UX, Solaris and OpenBSD), Microsoft Windows, Mac OS X, RISC OS, and probably others. PHP has also support for most of the web servers today. This includes Apache, IIS, and many others. And this includes any web server that can utilize the FastCGI PHP binary, like lighttpd and nginx. PHP works as either a module, or as a CGI processor. So with PHP, you have the freedom of choosing an operating system and a web server. Furthermore, you also have the choice of using procedural programming or object oriented programming (OOP), or a mixture of them both. With PHP you are not limited to output HTML. PHP's abilities includes outputting images, PDF files and even Flash movies (using libswf and Ming) generated on the fly. You can also output easily any text, such as XHTML and any other XML file. PHP can autogenerate these files, and save them in the file system, instead of printing it out, forming a server-side cache for your dynamic content. One of the strongest and most significant features in PHP is its support for a wide range of databases. Writing a database-enabled web page is incredibly simple using one of the database specific extensions (e.g., for mysql), or using an abstraction layer like PDO, or connect to any database supporting the Open Database Connection standard via the ODBC extension. Other databases may utilize cURL or sockets, like CouchDB. PHP also has support for talking to other services using protocols such as LDAP, IMAP, SNMP, NNTP, POP3, HTTP, COM (on Windows) and countless others. You can also open raw network sockets and interact using any other protocol. PHP has support for the WDDX complex data exchange between virtually all Web programming languages. Talking about interconnection, PHP has support for instantiation of Java objects and using them transparently as PHP objects. PHP has useful text processing features, which includes the Perl compatible regular expressions (PCRE), and many extensions and tools to parse and access XML documents. PHP standardizes all of the XML extensions on the solid base of libxml2, and extends the feature set adding SimpleXML, XMLReader and XMLWriter support. And many other interesting extensions exist, which are categorized both alphabetically and by category. And there are additional PECL extensions that may or may not be documented within the PHP manual itself, like >> XDebug. As you can see this page is not enough to list all the features and benefits PHP can offer. Read on in the sections about installing PHP, and see the function reference part for explanation of the extensions mentioned here. ---------------------------------------------------------------------- ---------------------------------------------------------------------- ---------------------------------------------------------------------- A simple tutorial Table of Contents * What do I need? * Your first PHP-enabled page * Something Useful * Dealing with Forms * Using old code with new versions of PHP * What's next? Here we would like to show the very basics of PHP in a short, simple tutorial. This text only deals with dynamic web page creation with PHP, though PHP is not only capable of creating web pages. See the section titled What can PHP do for more information. PHP-enabled web pages are treated just like regular HTML pages and you can create and edit them the same way you normally create regular HTML pages. ---------------------------------------------------------------------- What do I need? In this tutorial we assume that your server has activated support for PHP and that all files ending in .php are handled by PHP. On most servers, this is the default extension for PHP files, but ask your server administrator to be sure. If your server supports PHP, then you do not need to do anything. Just create your .php files, put them in your web directory and the server will automatically parse them for you. There is no need to compile anything nor do you need to install any extra tools. Think of these PHP-enabled files as simple HTML files with a whole new family of magical tags that let you do all sorts of things. Most web hosts offer PHP support, but if your host does not, consider reading the >> PHP Links section for resources on finding PHP enabled web hosts. Let us say you want to save precious bandwidth and develop locally. In this case, you will want to install a web server, such as >> Apache, and of course >> PHP. You will most likely want to install a database as well, such as >> MySQL. You can either install these individually or choose a simpler way. Our manual has installation instructions for PHP (assuming you already have some web server set up). In case you have problems with installing PHP yourself, we would suggest you ask your questions on our >> installation mailing list. If you choose to go on the simpler route, then >> locate a pre-configured package for your operating system, which automatically installs all of these with just a few mouse clicks. It is easy to setup a web server with PHP support on any operating system, including MacOSX, Linux and Windows. On Linux, you may find >> rpmfind and >> PBone helpful for locating RPMs. You may also want to visit >> apt-get to find packages for Debian. ---------------------------------------------------------------------- ---------------------------------------------------------------------- Your first PHP-enabled page Create a file named hello.php and put it in your web server's root directory (DOCUMENT_ROOT) with the following content: Example #1 Our first PHP script: hello.php PHP Test Hello World

'; ?> Use your browser to access the file with your web server's URL, ending with the /hello.php file reference. When developing locally this URL will be something like http://localhost/hello.php or http://127.0.0.1/hello.php but this depends on the web server's configuration. If everything is configured correctly, this file will be parsed by PHP and the following output will be sent to your browser: PHP Test

Hello World

This program is extremely simple and you really did not need to use PHP to create a page like this. All it does is display: Hello World using the PHP echo() statement. Note that the file does not need to be executable or special in any way. The server finds out that this file needs to be interpreted by PHP because you used the ".php" extension, which the server is configured to pass on to PHP. Think of this as a normal HTML file which happens to have a set of special tags available to you that do a lot of interesting things. If you tried this example and it did not output anything, it prompted for download, or you see the whole file as text, chances are that the server you are on does not have PHP enabled, or is not configured properly. Ask your administrator to enable it for you using the Installation chapter of the manual. If you are developing locally, also read the installation chapter to make sure everything is configured properly. Make sure that you access the file via http with the server providing you the output. If you just call up the file from your file system, then it will not be parsed by PHP. If the problems persist anyway, do not hesitate to use one of the many >> PHP support options. The point of the example is to show the special PHP tag format. In this example we used . You may jump in and out of PHP mode in an HTML file like this anywhere you want. For more details, read the manual section on the basic PHP syntax. Note: A Note on Line Feeds Line feeds have little meaning in HTML, however it is still a good idea to make your HTML look nice and clean by putting line feeds in. A linefeed that follows immediately after a closing ?> will be removed by PHP. This can be extremely useful when you are putting in many blocks of PHP or include files containing PHP that aren't supposed to output anything. At the same time it can be a bit confusing. You can put a space after the closing ?> to force a space and a line feed to be output, or you can put an explicit line feed in the last echo/print from within your PHP block. Note: A Note on Text Editors There are many text editors and Integrated Development Environments (IDEs) that you can use to create, edit and manage PHP files. A partial list of these tools is maintained at >> PHP Editors List. If you wish to recommend an editor, please visit the above page and ask the page maintainer to add the editor to the list. Having an editor with syntax highlighting can be helpful. Note: A Note on Word Processors Word processors such as StarOffice Writer, Microsoft Word and Abiword are not optimal for editing PHP files. If you wish to use one for this test script, you must ensure that you save the file as plain text or PHP will not be able to read and execute the script. Note: A Note on Windows Notepad If you are writing your PHP scripts using Windows Notepad, you will need to ensure that your files are saved with the .php extension. (Notepad adds a .txt extension to files automatically unless you take one of the following steps to prevent it.) When you save the file and are prompted to provide a name for the file, place the filename in quotes (i.e. "hello.php"). Alternatively, you can click on the 'Text Documents' drop-down menu in the 'Save' dialog box and change the setting to "All Files". You can then enter your filename without quotes. Now that you have successfully created a working PHP script, it is time to create the most famous PHP script! Make a call to the phpinfo() function and you will see a lot of useful information about your system and setup such as available predefined variables, loaded PHP modules, and configuration settings. Take some time and review this important information. Example #2 Get system information from PHP ---------------------------------------------------------------------- ---------------------------------------------------------------------- Something Useful Let us do something more useful now. We are going to check what sort of browser the visitor is using. For that, we check the user agent string the browser sends as part of the HTTP request. This information is stored in a variable. Variables always start with a dollar-sign in PHP. The variable we are interested in right now is $_SERVER['HTTP_USER_AGENT']. Note: $_SERVER is a special reserved PHP variable that contains all web server information. It is known as a superglobal. See the related manual page on superglobals for more information. These special variables were introduced in PHP >> 4.1.0. Before this time, we used the older $HTTP_*_VARS arrays instead, such as $HTTP_SERVER_VARS. Although deprecated, these older variables still exist. (See also the note on old code.) To display this variable, you can simply do: Example #1 Printing a variable (Array element) A sample output of this script may be: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1) There are many types of variables available in PHP. In the above example we printed an Array element. Arrays can be very useful. $_SERVER is just one variable that PHP automatically makes available to you. A list can be seen in the Reserved Variables section of the manual or you can get a complete list of them by looking at the output of the phpinfo() function used in the example in the previous section. You can put multiple PHP statements inside a PHP tag and create little blocks of code that do more than just a single echo. For example, if you want to check for Internet Explorer you can do this: Example #2 Example using control structures and functions '; } ?> A sample output of this script may be: You are using Internet Explorer.
Here we introduce a couple of new concepts. We have an if statement. If you are familiar with the basic syntax used by the C language, this should look logical to you. Otherwise, you should probably pick up an introductory PHP book and read the first couple of chapters, or read the Language Reference part of the manual. The second concept we introduced was the strpos() function call. strpos() is a function built into PHP which searches a string for another string. In this case we are looking for 'MSIE' (so-called needle) inside $_SERVER['HTTP_USER_AGENT'] (so-called haystack). If the needle is found inside the haystack, the function returns the position of the needle relative to the start of the haystack. Otherwise, it returns FALSE. If it does not return FALSE, the if expression evaluates to TRUE and the code within its {braces} is executed. Otherwise, the code is not run. Feel free to create similar examples, with if, else, and other functions such as strtoupper() and strlen(). Each related manual page contains examples too. If you are unsure how to use functions, you will want to read both the manual page on how to read a function definition and the section about PHP functions. We can take this a step further and show how you can jump in and out of PHP mode even in the middle of a PHP block: Example #3 Mixing both HTML and PHP modes

strpos() must have returned non-false

You are using Internet Explorer

strpos() must have returned false

You are not using Internet Explorer

A sample output of this script may be:

strpos() must have returned non-false

You are using Internet Explorer

Instead of using a PHP echo statement to output something, we jumped out of PHP mode and just sent straight HTML. The important and powerful point to note here is that the logical flow of the script remains intact. Only one of the HTML blocks will end up getting sent to the viewer depending on the result of strpos(). In other words, it depends on whether the string MSIE was found or not. ---------------------------------------------------------------------- ---------------------------------------------------------------------- Dealing with Forms One of the most powerful features of PHP is the way it handles HTML forms. The basic concept that is important to understand is that any form element will automatically be available to your PHP scripts. Please read the manual section on Variables from external sources for more information and examples on using forms with PHP. Here is an example HTML form: Example #1 A simple HTML form

Your name:

Your age:

There is nothing special about this form. It is a straight HTML form with no special tags of any kind. When the user fills in this form and hits the submit button, the action.php page is called. In this file you would write something like this: Example #2 Printing data from our form Hi . You are years old. A sample output of this script may be: Hi Joe. You are 22 years old. Apart from the htmlspecialchars() and (int) parts, it should be obvious what this does. htmlspecialchars() makes sure any characters that are special in html are properly encoded so people can't inject HTML tags or Javascript into your page. For the age field, since we know it is a number, we can just convert it to an integer which will automatically get rid of any stray characters. You can also have PHP do this for you automatically by using the filter extension. The $_POST['name'] and $_POST['age'] variables are automatically set for you by PHP. Earlier we used the $_SERVER superglobal; above we just introduced the $_POST superglobal which contains all POST data. Notice how the method of our form is POST. If we used the method GET then our form information would live in the $_GET superglobal instead. You may also use the $_REQUEST superglobal, if you do not care about the source of your request data. It contains the merged information of GET, POST and COOKIE data. Also see the import_request_variables() function. You can also deal with XForms input in PHP, although you will find yourself comfortable with the well supported HTML forms for quite some time. While working with XForms is not for beginners, you might be interested in them. We also have a short introduction to handling data received from XForms in our features section. ---------------------------------------------------------------------- ---------------------------------------------------------------------- Using old code with new versions of PHP Now that PHP has grown to be a popular scripting language, there are a lot of public repositories and libraries containing code you can reuse. The PHP developers have largely tried to preserve backwards compatibility, so a script written for an older version will run (ideally) without changes in a newer version of PHP. In practice, some changes will usually be needed. Two of the most important recent changes that affect old code are: * The deprecation of the old $HTTP_*_VARS arrays (which need to be indicated as global when used inside a function or method). The following superglobal arrays were introduced in PHP >> 4.1.0. They are: $_GET, $_POST, $_COOKIE, $_SERVER, $_FILES, $_ENV, $_REQUEST, and $_SESSION. The older $HTTP_*_VARS arrays, such as $HTTP_POST_VARS, also exist. As of PHP 5.0.0, the long PHP predefined variable arrays may be disabled with the register_long_arrays directive. * External variables are no longer registered in the global scope by default. In other words, as of PHP >> 4.2.0 the PHP directive register_globals is off by default in php.ini. The preferred method of accessing these values is via the superglobal arrays mentioned above. Older scripts, books, and tutorials may rely on this directive being on. If it were on, for example, one could use $id from the URL http://www.example.com/foo.php?id=42. Whether on or off, $_GET['id'] is available. For more details on these changes, see the section on predefined variables and links therein. ---------------------------------------------------------------------- ---------------------------------------------------------------------- What's next? With your new knowledge you should be able to understand most of the manual and also the various example scripts available in the example archives. You can also find other examples on the php.net websites in the links section: >> http://www.php.net/links.php. To view various slide presentations that show more of what PHP can do, see the PHP Conference Material Site: >> http://talks.php.net/ ---------------------------------------------------------------------- ---------------------------------------------------------------------- * Introduction * What is PHP? * What can PHP do? * A simple tutorial * What do I need? * Your first PHP-enabled page * Something Useful * Dealing with Forms * Using old code with new versions of PHP * What's next? ---------------------------------------------------------------------- ---------------------------------------------------------------------- Installation and Configuration ---------------------------------------------------------------------- General Installation Considerations Before starting the installation, first you need to know what do you want to use PHP for. There are three main fields you can use PHP, as described in the What can PHP do? section: * Websites and web applications (server-side scripting) * Command line scripting * Desktop (GUI) applications For the first and most common form, you need three things: PHP itself, a web server and a web browser. You probably already have a web browser, and depending on your operating system setup, you may also have a web server (e.g. Apache on Linux and MacOS X; IIS on Windows). You may also rent webspace at a company. This way, you don't need to set up anything on your own, only write your PHP scripts, upload it to the server you rent, and see the results in your browser. In case of setting up the server and PHP on your own, you have two choices for the method of connecting PHP to the server. For many servers PHP has a direct module interface (also called SAPI). These servers include Apache, Microsoft Internet Information Server, Netscape and iPlanet servers. Many other servers have support for ISAPI, the Microsoft module interface (OmniHTTPd for example). If PHP has no module support for your web server, you can always use it as a CGI or FastCGI processor. This means you set up your server to use the CGI executable of PHP to process all PHP file requests on the server. If you are also interested to use PHP for command line scripting (e.g. write scripts autogenerating some images for you offline, or processing text files depending on some arguments you pass to them), you always need the command line executable. For more information, read the section about writing command line PHP applications. In this case, you need no server and no browser. With PHP you can also write desktop GUI applications using the PHP-GTK extension. This is a completely different approach than writing web pages, as you do not output any HTML, but manage windows and objects within them. For more information about PHP-GTK, please >> visit the site dedicated to this extension. PHP-GTK is not included in the official PHP distribution. From now on, this section deals with setting up PHP for web servers on Unix and Windows with server module interfaces and CGI executables. You will also find information on the command line executable in the following sections. PHP source code and binary distributions for Windows can be found at >> http://www.php.net/downloads.php. We recommend you to choose a >> mirror nearest to you for downloading the distributions. ---------------------------------------------------------------------- ---------------------------------------------------------------------- Installation on Unix systems Table of Contents * Apache 1.3.x on Unix systems * Apache 2.x on Unix systems * Lighttpd 1.4 on Unix systems * Sun, iPlanet and Netscape servers on Sun Solaris * CGI and command line setups * HP-UX specific installation notes * OpenBSD installation notes * Solaris specific installation tips * Debian GNU/Linux installation notes This section will guide you through the general configuration and installation of PHP on Unix systems. Be sure to investigate any sections specific to your platform or web server before you begin the process. As our manual outlines in the General Installation Considerations section, we are mainly dealing with web centric setups of PHP in this section, although we will cover setting up PHP for command line usage as well. There are several ways to install PHP for the Unix platform, either with a compile and configure process, or through various pre-packaged methods. This documentation is mainly focused around the process of compiling and configuring PHP. Many Unix like systems have some sort of package installation system. This can assist in setting up a standard configuration, but if you need to have a different set of features (such as a secure server, or a different database driver), you may need to build PHP and/or your web server. If you are unfamiliar with building and compiling your own software, it is worth checking to see whether somebody has already built a packaged version of PHP with the features you need. Prerequisite knowledge and software for compiling: * Basic Unix skills (being able to operate "make" and a C compiler) * An ANSI C compiler * A web server * Any module specific components (such as GD, PDF libs, etc.) When building directly from SVN sources or after custom modifications you might also need: * autoconf: 2.13+ (for PHP < 5.4.0), 2.59+ (for PHP >= 5.4.0) * automake: 1.4+ * libtool: 1.4.x+ (except 1.4.2) * re2c: Version 0.13.4 or newer * flex: Version 2.5.4 (for PHP <= 5.2) * bison: Version 1.28 (preferred), 1.35, or 1.75 The initial PHP setup and configuration process is controlled by the use of the command line options of the configure script. You could get a list of all available options along with short explanations running ./configure --help. Our manual documents the different options separately. You will find the core options in the appendix, while the different extension specific options are descibed on the reference pages. When PHP is configured, you are ready to build the module and/or executables. The command make should take care of this. If it fails and you can't figure out why, see the Problems section. ---------------------------------------------------------------------- Apache 1.3.x on Unix systems This section contains notes and hints specific to Apache installs of PHP on Unix platforms. We also have instructions and notes for Apache 2 on a separate page. You can select arguments to add to the configure on line 10 below from the list of core configure options and from extension specific options described at the respective places in the manual. The version numbers have been omitted here, to ensure the instructions are not incorrect. You will need to replace the 'xxx' here with the correct values from your files. Example #1 Installation Instructions (Apache Shared Module Version) for PHP 1. gunzip apache_xxx.tar.gz 2. tar -xvf apache_xxx.tar 3. gunzip php-xxx.tar.gz 4. tar -xvf php-xxx.tar 5. cd apache_xxx 6. ./configure --prefix=/www --enable-module=so 7. make 8. make install 9. cd ../php-xxx 10. Now, configure your PHP. This is where you customize your PHP with various options, like which extensions will be enabled. Do a ./configure --help for a list of available options. In our example we'll do a simple configure with Apache 1 and MySQL support. Your path to apxs may differ from our example. ./configure --with-mysql --with-apxs=/www/bin/apxs 11. make 12. make install If you decide to change your configure options after installation, you only need to repeat the last three steps. You only need to restart apache for the new module to take effect. A recompile of Apache is not needed. Note that unless told otherwise, 'make install' will also install PEAR, various PHP tools such as phpize, install the PHP CLI, and more. 13. Setup your php.ini file: cp php.ini-development /usr/local/lib/php.ini You may edit your .ini file to set PHP options. If you prefer your php.ini in another location, use --with-config-file-path=/some/path in step 10. If you instead choose php.ini-production, be certain to read the list of changes within, as they affect how PHP behaves. 14. Edit your httpd.conf to load the PHP module. The path on the right hand side of the LoadModule statement must point to the path of the PHP module on your system. The make install from above may have already added this for you, but be sure to check. LoadModule php5_module libexec/libphp5.so 15. And in the AddModule section of httpd.conf, somewhere under the ClearModuleList, add this: AddModule mod_php5.c 16. Tell Apache to parse certain extensions as PHP. For example, let's have Apache parse the .php extension as PHP. You could have any extension(s) parse as PHP by simply adding more, with each separated by a space. We'll add .phtml to demonstrate. AddType application/x-httpd-php .php .phtml It's also common to setup the .phps extension to show highlighted PHP source, this can be done with: AddType application/x-httpd-php-source .phps 17. Use your normal procedure for starting the Apache server. (You must stop and restart the server, not just cause the server to reload by using a HUP or USR1 signal.) Alternatively, to install PHP as a static object: Example #2 Installation Instructions (Static Module Installation for Apache) for PHP 1. gunzip -c apache_1.3.x.tar.gz | tar xf - 2. cd apache_1.3.x 3. ./configure 4. cd .. 5. gunzip -c php-5.x.y.tar.gz | tar xf - 6. cd php-5.x.y 7. ./configure --with-mysql --with-apache=../apache_1.3.x 8. make 9. make install 10. cd ../apache_1.3.x 11. ./configure --prefix=/www --activate-module=src/modules/php5/libphp5.a (The above line is correct! Yes, we know libphp5.a does not exist at this stage. It isn't supposed to. It will be created.) 12. make (you should now have an httpd binary which you can copy to your Apache bin dir if it is your first install then you need to "make install" as well) 13. cd ../php-5.x.y 14. cp php.ini-development /usr/local/lib/php.ini 15. You can edit /usr/local/lib/php.ini file to set PHP options. Edit your httpd.conf or srm.conf file and add: AddType application/x-httpd-php .php Depending on your Apache install and Unix variant, there are many possible ways to stop and restart the server. Below are some typical lines used in restarting the server, for different apache/unix installations. You should replace /path/to/ with the path to these applications on your systems. Example #3 Example commands for restarting Apache 1. Several Linux and SysV variants: /etc/rc.d/init.d/httpd restart 2. Using apachectl scripts: /path/to/apachectl stop /path/to/apachectl start 3. httpdctl and httpsdctl (Using OpenSSL), similar to apachectl: /path/to/httpsdctl stop /path/to/httpsdctl start 4. Using mod_ssl, or another SSL server, you may want to manually stop and start: /path/to/apachectl stop /path/to/apachectl startssl The locations of the apachectl and http(s)dctl binaries often vary. If your system has locate or whereis or which commands, these can assist you in finding your server control programs. Different examples of compiling PHP for apache are as follows: ./configure --with-apxs --with-pgsql This will create a libphp5.so shared library that is loaded into Apache using a LoadModule line in Apache's httpd.conf file. The PostgreSQL support is embedded into this library. ./configure --with-apxs --with-pgsql=shared This will create a libphp5.so shared library for Apache, but it will also create a pgsql.so shared library that is loaded into PHP either by using the extension directive in php.ini file or by loading it explicitly in a script using the dl() function. ./configure --with-apache=/path/to/apache_source --with-pgsql This will create a libmodphp5.a library, a mod_php5.c and some accompanying files and copy this into the src/modules/php5 directory in the Apache source tree. Then you compile Apache using --activate-module=src/modules/php5/libphp5.a and the Apache build system will create libphp5.a and link it statically into the httpd binary. The PostgreSQL support is included directly into this httpd binary, so the final result here is a single httpd binary that includes all of Apache and all of PHP. ./configure --with-apache=/path/to/apache_source --with-pgsql=shared Same as before, except instead of including PostgreSQL support directly into the final httpd you will get a pgsql.so shared library that you can load into PHP from either the php.ini file or directly using dl(). When choosing to build PHP in different ways, you should consider the advantages and drawbacks of each method. Building as a shared object will mean that you can compile apache separately, and don't have to recompile everything as you add to, or change, PHP. Building PHP into apache (static method) means that PHP will load and run faster. For more information, see the Apache >> web page on DSO support. Note: Apache's default httpd.conf currently ships with a section that looks like this: User nobody Group "#-1" Unless you change that to "Group nogroup" or something like that ("Group daemon" is also very common) PHP will not be able to open files. Note: Make sure you specify the installed version of apxs when using --with-apxs=/path/to/apxs . You must NOT use the apxs version that is in the apache sources but the one that is actually installed on your system. ---------------------------------------------------------------------- ---------------------------------------------------------------------- Apache 2.x on Unix systems This section contains notes and hints specific to Apache 2.x installs of PHP on Unix systems. Warning We do not recommend using a threaded MPM in production with Apache 2. Use the prefork MPM, which is the default MPM with Apache 2.0 and 2.2. For information on why, read the related FAQ entry on using Apache2 with a threaded MPM The >> Apache Documentation is the most authoritative source of information on the Apache 2.x server. More information about installation options for Apache may be found there. The most recent version of Apache HTTP Server may be obtained from >> Apache download site, and a fitting PHP version from the above mentioned places. This quick guide covers only the basics to get started with Apache 2.x and PHP. For more information read the >> Apache Documentation. The version numbers have been omitted here, to ensure the instructions are not incorrect. In the examples below, 'NN' should be replaced with the specific version of Apache being used. There are currently two versions of Apache 2.x - there's 2.0 and 2.2. While there are various reasons for choosing each, 2.2 is the current latest version, and the one that is recommended, if that option is available to you. However, the instructions here will work for either 2.0 or 2.2. 1. Obtain the Apache HTTP server from the location listed above, and unpack it: gzip -d httpd-2_x_NN.tar.gz tar -xf httpd-2_x_NN.tar 2. Likewise, obtain and unpack the PHP source: gunzip php-NN.tar.gz tar -xf php-NN.tar 3. Build and install Apache. Consult the Apache install documentation for more details on building Apache. cd httpd-2_x_NN ./configure --enable-so make make install 4. Now you have Apache 2.x.NN available under /usr/local/apache2, configured with loadable module support and the standard MPM prefork. To test the installation use your normal procedure for starting the Apache server, e.g.: /usr/local/apache2/bin/apachectl start and stop the server to go on with the configuration for PHP: /usr/local/apache2/bin/apachectl stop 5. Now, configure and build PHP. This is where you customize PHP with various options, like which extensions will be enabled. Run ./configure --help for a list of available options. In our example we'll do a simple configure with Apache 2 and MySQL support. If you built Apache from source, as described above, the below example will match your path for apxs, but if you installed Apache some other way, you'll need to adjust the path to apxs accordingly. Note that some distros may rename apxs to apxs2. cd ../php-NN ./configure --with-apxs2=/usr/local/apache2/bin/apxs --with-mysql make make install If you decide to change your configure options after installation, you'll need to re-run the configure, make, and make install steps. You only need to restart apache for the new module to take effect. A recompile of Apache is not needed. Note that unless told otherwise, 'make install' will also install PEAR, various PHP tools such as phpize, install the PHP CLI, and more. 6. Setup your php.ini cp php.ini-development /usr/local/lib/php.ini You may edit your .ini file to set PHP options. If you prefer having php.ini in another location, use --with-config-file-path=/some/path in step 5. If you instead choose php.ini-production, be certain to read the list of changes within, as they affect how PHP behaves. 7. Edit your httpd.conf to load the PHP module. The path on the right hand side of the LoadModule statement must point to the path of the PHP module on your system. The make install from above may have already added this for you, but be sure to check. LoadModule php5_module modules/libphp5.so 8. Tell Apache to parse certain extensions as PHP. For example, let's have Apache parse .php files as PHP. Instead of only using the Apache AddType directive, we want to avoid potentially dangerous uploads and created files such as exploit.php.jpg from being executed as PHP. Using this example, you could have any extension(s) parse as PHP by simply adding them. We'll add .php to demonstrate. SetHandler application/x-httpd-php Or, if we wanted to allow .php, .php2, .php3, .php4, .php5, .php6, and .phtml files to be executed as PHP, but nothing else, we'd use this: SetHandler application/x-httpd-php And to allow .phps files to be handled by the php source filter, and displayed as syntax-highlighted source code, use this: SetHandler application/x-httpd-php-source mod_rewrite may be used To allow any arbitrary .php file to be displayed as syntax-highlighted source code, without having to rename or copy it to a .phps file: RewriteEngine On RewriteRule (.*\.php)s$ $1 [H=application/x-httpd-php-source] The php source filter should not be enabled on production systems, where it may expose confidential or otherwise sensitive information embedded in source code. 9. Use your normal procedure for starting the Apache server, e.g.: /usr/local/apache2/bin/apachectl start OR service httpd restart Following the steps above you will have a running Apache2 web server with support for PHP as a SAPI module. Of course there are many more configuration options available Apache and PHP. For more information type ./configure --help in the corresponding source tree. Apache may be built multithreaded by selecting the worker MPM, rather than the standard prefork MPM, when Apache is built. This is done by adding the following option to the argument passed to ./configure, in step 3 above: --with-mpm=worker This should not be undertaken without being aware of the consequences of this decision, and having at least a fair understanding of the implications. The Apache documentation regarding >> MPM-Modules discusses MPMs in a great deal more detail. Note: The Apache MultiViews FAQ discusses using multiviews with PHP. Note: To build a multithreaded version of Apache, the target system must support threads. In this case, PHP should also be built with experimental Zend Thread Safety (ZTS). Under this configuration, not all extensions will be available. The recommended setup is to build Apache with the default prefork MPM-Module. ---------------------------------------------------------------------- ---------------------------------------------------------------------- Lighttpd 1.4 on Unix systems This section contains notes and hints specific to Lighttpd 1.4 installs of PHP on Unix systems. Please use the >> Lighttpd trac to learn how to install Lighttpd properly before continuing. Fastcgi is the preferred SAPI to connect PHP and Lighttpd. Fastcgi is automagically enabled in php-cgi in PHP 5.3, but for older versions configure PHP with --enable-fastcgi. To confirm that PHP has fastcgi enabled, php -v should contain PHP 5.2.5 (cgi-fcgi) Before PHP 5.2.3, fastcgi was enabled on the php binary (there was no php-cgi). Letting Lighttpd spawn php processes To configure Lighttpd to connect to php and spawn fastcgi processes, edit lighttpd.conf. Sockets are preferred to connect to fastcgi processes on the local system. Example #1 Partial lighttpd.conf server.modules += ( "mod_fastcgi" ) fastcgi.server = ( ".php" => (( "socket" => "/tmp/php.socket", "bin-path" => "/usr/local/bin/php-cgi", "bin-environment" => ( "PHP_FCGI_CHILDREN" => "16", "PHP_FCGI_MAX_REQUESTS" => "10000" ), "min-procs" => 1, "max-procs" => 1, "idle-timeout" => 20 )) ) The bin-path directive allows lighttpd to spawn fastcgi processes dynamically. PHP will spawn children according to the PHP_FCGI_CHILDREN environment variable. The "bin-environment" directive sets the environment for the spawned processes. PHP will kill a child process after the number of requests specified by PHP_FCGI_MAX_REQUESTS is reached. The directives "min-procs" and "max-procs" should generally be avoided with PHP. PHP manages its own children and opcode caches like APC will only share among children managed by PHP. If "min-procs" is set to something greater than 1, the total number of php responders will be multiplied PHP_FCGI_CHILDREN (2 min-procs * 16 children gives 32 responders). Spawning with spawn-fcgi Lighttpd provides a program called spawn-fcgi to ease the process of spawning fastcgi processes easier. Spawning php-cgi It is possible to spawn processes without spawn-fcgi, though a bit of heavy-lifting is required. Setting the PHP_FCGI_CHILDREN environment var controls how many children PHP will spawn to handle incoming requests. Setting PHP_FCGI_MAX_REQUESTS will determine how long (in requests) each child will live. Here's a simple bash script to help spawn php responders. Example #2 Spawning FastCGI Responders #!/bin/sh # Location of the php-cgi binary PHP=/usr/local/bin/php-cgi # PID File location PHP_PID=/tmp/php.pid # Binding to an address #FCGI_BIND_ADDRESS=10.0.1.1:10000 # Binding to a domain socket FCGI_BIND_ADDRESS=/tmp/php.sock PHP_FCGI_CHILDREN=16 PHP_FCGI_MAX_REQUESTS=10000 env -i PHP_FCGI_CHILDREN=$PHP_FCGI_CHILDREN \ PHP_FCGI_MAX_REQUESTS=$PHP_FCGI_MAX_REQUESTS \ $PHP -b $FCGI_BIND_ADDRESS & echo $! > "$PHP_PID" Connecting to remote FCGI instances Fastcgi instances can be spawned on multiple remote machines in order to scale applications. Example #3 Connecting to remote php-fastcgi instances fastcgi.server = ( ".php" => (( "host" => "10.0.0.2", "port" => 1030 ), ( "host" => "10.0.0.3", "port" => 1030 )) ) ---------------------------------------------------------------------- ---------------------------------------------------------------------- Sun, iPlanet and Netscape servers on Sun Solaris This section contains notes and hints specific to Sun Java System Web Server, Sun ONE Web Server, iPlanet and Netscape server installs of PHP on Sun Solaris. From PHP 4.3.3 on you can use PHP scripts with the NSAPI module to generate custom directory listings and error pages. Additional functions for Apache compatibility are also available. For support in current web servers read the note about subrequests. You can find more information about setting up PHP for the Netscape Enterprise Server (NES) here: >> http://benoit.noss.free.fr/php/install-php4.html To build PHP with Sun JSWS/Sun ONE WS/iPlanet/Netscape web servers, enter the proper install directory for the --with-nsapi=[DIR] option. The default directory is usually /opt/netscape/suitespot/. Please also read /php-xxx-version/sapi/nsapi/nsapi-readme.txt. 1. Install the following packages from >> http://www.sunfreeware.com/ or another download site: * autoconf-2.13 * automake-1.4 * bison-1_25-sol26-sparc-local * flex-2_5_4a-sol26-sparc-local * gcc-2_95_2-sol26-sparc-local * gzip-1.2.4-sol26-sparc-local * m4-1_4-sol26-sparc-local * make-3_76_1-sol26-sparc-local * mysql-3.23.24-beta (if you want mysql support) * perl-5_005_03-sol26-sparc-local * tar-1.13 (GNU tar) 2. Make sure your path includes the proper directories PATH=.:/usr/local/bin:/usr/sbin:/usr/bin:/usr/ccs/bin and make it available to your system export PATH. 3. gunzip php-x.x.x.tar.gz (if you have a .gz dist, otherwise go to 4). 4. tar xvf php-x.x.x.tar 5. Change to your extracted PHP directory: cd ../php-x.x.x 6. For the following step, make sure /opt/netscape/suitespot/ is where your netscape server is installed. Otherwise, change to the correct path and run: ./configure --with-mysql=/usr/local/mysql \ --with-nsapi=/opt/netscape/suitespot/ \ --enable-libgcc 7. Run make followed by make install. After performing the base install and reading the appropriate readme file, you may need to perform some additional configuration steps. Configuration Instructions for Sun/iPlanet/Netscape Firstly you may need to add some paths to the LD_LIBRARY_PATH environment for the server to find all the shared libs. This can best done in the start script for your web server. The start script is often located in: /path/to/server/https-servername/start. You may also need to edit the configuration files that are located in: /path/to/server/https-servername/config/. 1. Add the following line to mime.types (you can do that by the administration server): type=magnus-internal/x-httpd-php exts=php 2. Edit magnus.conf (for servers >= 6) or obj.conf (for servers < 6) and add the following, shlib will vary depending on your system, it will be something like /opt/netscape/suitespot/bin/libphp4.so. You should place the following lines after mime types init. Init fn="load-modules" funcs="php4_init,php4_execute,php4_auth_trans" shlib="/opt/netscape/suitespot/bin/libphp4.so" Init fn="php4_init" LateInit="yes" errorString="Failed to initialize PHP!" [php_ini="/path/to/php.ini"] (PHP >= 4.3.3) The php_ini parameter is optional but with it you can place your php.ini in your web server config directory. 3. Configure the default object in obj.conf (for virtual server classes [version 6.0+] in their vserver.obj.conf): . . . .#NOTE this next line should happen after all 'ObjectType' and before all 'AddLog' lines Service fn="php4_execute" type="magnus-internal/x-httpd-php" [inikey=value inikey=value ...] . . (PHP >= 4.3.3) As additional parameters you can add some special php.ini-values, for example you can set a docroot="/path/to/docroot" specific to the context php4_execute is called. For boolean ini-keys please use 0/1 as value, not "On","Off",... (this will not work correctly), e.g. zlib.output_compression=1 instead of zlib.output_compression="On" 4. This is only needed if you want to configure a directory that only consists of PHP scripts (same like a cgi-bin directory): ObjectType fn="force-type" type="magnus-internal/x-httpd-php" Service fn=php4_execute [inikey=value inikey=value ...] After that you can configure a directory in the Administration server and assign it the style x-httpd-php. All files in it will get executed as PHP. This is nice to hide PHP usage by renaming files to .html. 5. Setup of authentication: PHP authentication cannot be used with any other authentication. ALL AUTHENTICATION IS PASSED TO YOUR PHP SCRIPT. To configure PHP Authentication for the entire server, add the following line to your default object: AuthTrans fn=php4_auth_trans . . . 6. To use PHP Authentication on a single directory, add the following: AuthTrans fn=php4_auth_trans Note: The stacksize that PHP uses depends on the configuration of the web server. If you get crashes with very large PHP scripts, it is recommended to raise it with the Admin Server (in the section "MAGNUS EDITOR"). CGI environment and recommended modifications in php.ini Important when writing PHP scripts is the fact that Sun JSWS/Sun ONE WS/iPlanet/Netscape is a multithreaded web server. Because of that all requests are running in the same process space (the space of the web server itself) and this space has only one environment. If you want to get CGI variables like PATH_INFO, HTTP_HOST etc. it is not the correct way to try this in the old PHP way with getenv() or a similar way (register globals to environment, $_ENV). You would only get the environment of the running web server without any valid CGI variables! Note: Why are there (invalid) CGI variables in the environment? Answer: This is because you started the web server process from the admin server which runs the startup script of the web server, you wanted to start, as a CGI script (a CGI script inside of the admin server!). This is why the environment of the started web server has some CGI environment variables in it. You can test this by starting the web server not from the administration server. Use the command line as root user and start it manually - you will see there are no CGI-like environment variables. Simply change your scripts to get CGI variables in the correct way for PHP 4.x by using the superglobal $_SERVER. If you have older scripts which use $HTTP_HOST, etc., you should turn on register_globals in php.ini and change the variable order too (important: remove "E" from it, because you do not need the environment here): variables_order = "GPCS" register_globals = On Special use for error pages or self-made directory listings (PHP >= 4.3.3) You can use PHP to generate the error pages for "404 Not Found" or similar. Add the following line to the object in obj.conf for every error page you want to overwrite: Error fn="php4_execute" code=XXX script="/path/to/script.php" [inikey=value inikey=value...] where XXX is the HTTP error code. Please delete any other Error directives which could interfere with yours. If you want to place a page for all errors that could exist, leave the code parameter out. Your script can get the HTTP status code with $_SERVER['ERROR_TYPE']. Another possibility is to generate self-made directory listings. Just create a PHP script which displays a directory listing and replace the corresponding default Service line for type="magnus-internal/directory" in obj.conf with the following: Service fn="php4_execute" type="magnus-internal/directory" script="/path/to/script.php" [inikey=value inikey=value...] For both error and directory listing pages the original URI and translated URI are in the variables $_SERVER['PATH_INFO'] and $_SERVER['PATH_TRANSLATED']. Note about nsapi_virtual() and subrequests (PHP >= 4.3.3) The NSAPI module now supports the nsapi_virtual() function (alias: virtual()) to make subrequests on the web server and insert the result in the web page. This function uses some undocumented features from the NSAPI library. On Unix the module automatically looks for the needed functions and uses them if available. If not, nsapi_virtual() is disabled. Note: But be warned: Support for nsapi_virtual() is EXPERIMENTAL!!! ---------------------------------------------------------------------- ---------------------------------------------------------------------- CGI and command line setups By default, PHP is built as both a CLI and CGI program, which can be used for CGI processing. If you are running a web server that PHP has module support for, you should generally go for that solution for performance reasons. However, the CGI version enables users to run different PHP-enabled pages under different user-ids. Warning A server deployed in CGI mode is open to several possible vulnerabilities. Please read our CGI security section to learn how to defend yourself from such attacks. Testing If you have built PHP as a CGI program, you may test your build by typing make test. It is always a good idea to test your build. This way you may catch a problem with PHP on your platform early instead of having to struggle with it later. Using Variables Some server supplied environment variables are not defined in the current >> CGI/1.1 specification. Only the following variables are defined there: AUTH_TYPE, CONTENT_LENGTH, CONTENT_TYPE, GATEWAY_INTERFACE, PATH_INFO, PATH_TRANSLATED, QUERY_STRING, REMOTE_ADDR, REMOTE_HOST, REMOTE_IDENT, REMOTE_USER, REQUEST_METHOD, SCRIPT_NAME, SERVER_NAME, SERVER_PORT, SERVER_PROTOCOL, and SERVER_SOFTWARE. Everything else should be treated as 'vendor extensions'. ---------------------------------------------------------------------- ---------------------------------------------------------------------- HP-UX specific installation notes This section contains notes and hints specific to installing PHP on HP-UX systems. There are two main options for installing PHP on HP-UX systems. Either compile it, or install a pre-compiled binary. Official pre-compiled packages are located here: >> http://software.hp.com/ Until this manual section is rewritten, the documentation about compiling PHP (and related extensions) on HP-UX systems has been removed. For now, consider reading the following external resource: >> Building Apache and PHP on HP-UX 11.11 ---------------------------------------------------------------------- ---------------------------------------------------------------------- OpenBSD installation notes This section contains notes and hints specific to installing PHP on >> OpenBSD 3.6. Using Binary Packages Using binary packages to install PHP on OpenBSD is the recommended and simplest method. The core package has been separated from the various modules, and each can be installed and removed independently from the others. The files you need can be found on your OpenBSD CD or on the FTP site. The main package you need to install is php4-core-4.3.8.tgz, which contains the basic engine (plus gettext and iconv). Next, take a look at the module packages, such as php4-mysql-4.3.8.tgz or php4-imap-4.3.8.tgz. You need to use the phpxs command to activate and deactivate these modules in your php.ini. Example #1 OpenBSD Package Install Example # pkg_add php4-core-4.3.8.tgz # /usr/local/sbin/phpxs -s # cp /usr/local/share/doc/php4/php.ini-recommended /var/www/conf/php.ini (add in mysql) # pkg_add php4-mysql-4.3.8.tgz # /usr/local/sbin/phpxs -a mysql (add in imap) # pkg_add php4-imap-4.3.8.tgz # /usr/local/sbin/phpxs -a imap (remove mysql as a test) # pkg_delete php4-mysql-4.3.8 # /usr/local/sbin/phpxs -r mysql (install the PEAR libraries) # pkg_add php4-pear-4.3.8.tgz Read the >> packages(7) manual page for more information about binary packages on OpenBSD. Using Ports You can also compile up PHP from source using the >> ports tree. However, this is only recommended for users familiar with OpenBSD. The PHP 4 port is split into two sub-directories: core and extensions. The extensions directory generates sub-packages for all of the supported PHP modules. If you find you do not want to create some of these modules, use the no_* FLAVOR. For example, to skip building the imap module, set the FLAVOR to no_imap. Common Problems * The default install of Apache runs inside a >> chroot(2) jail, which will restrict PHP scripts to accessing files under /var/www. You will therefore need to create a /var/www/tmp directory for PHP session files to be stored, or use an alternative session backend. In addition, database sockets need to be placed inside the jail or listen on the localhost interface. If you use network functions, some files from /etc such as /etc/resolv.conf and /etc/services will need to be moved into /var/www/etc. The OpenBSD PEAR package automatically installs into the correct chroot directories, so no special modification is needed there. More information on the OpenBSD Apache is available in the >> OpenBSD FAQ. * The OpenBSD 3.6 package for the >> gd extension requires XFree86 to be installed. If you do not wish to use some of the font features that require X11, install the php4-gd-4.3.8-no_x11.tgz package instead. Older Releases Older releases of OpenBSD used the FLAVORS system to compile up a statically linked PHP. Since it is hard to generate binary packages using this method, it is now deprecated. You can still use the old stable ports trees if you wish, but they are unsupported by the OpenBSD team. If you have any comments about this, the current maintainer for the port is Anil Madhavapeddy (avsm at openbsd dot org). ---------------------------------------------------------------------- ---------------------------------------------------------------------- Solaris specific installation tips This section contains notes and hints specific to installing PHP on Solaris systems. Required software Solaris installs often lack C compilers and their related tools. Read this FAQ for information on why using GNU versions for some of these tools is necessary. For unpacking the PHP distribution you need * tar * gzip or * bzip2 For compiling PHP you need * gcc (recommended, other C compilers may work) * make * GNU sed For building extra extensions or hacking the code of PHP you might also need * flex (up to PHP 5.2) * re2c * bison * m4 * autoconf * automake In addition, you will need to install (and possibly compile) any additional software specific to your configuration, such as Oracle or MySQL. Using Packages You can simplify the Solaris install process by using pkgadd to install most of your needed components. The Image Packaging System (IPS) for Solaris 11 Express also contains most of the required components for installation using the pkg command. ---------------------------------------------------------------------- ---------------------------------------------------------------------- Debian GNU/Linux installation notes This section contains notes and hints specific to installing PHP on >> Debian GNU/Linux. Warning Unofficial builds from third-parties are not supported here. Any bugs should be reported to the Debian team unless they can be reproduced using the latest builds from our >> download area. While the instructions for building PHP on Unix apply to Debian as well, this manual page contains specific information for other options, such as using either the apt-get or aptitude commands. This manual page uses these two commands interchangeably. Using APT First, note that other related packages may be desired like libapache2-mod-php5 to integrate with Apache 2, and php-pear for PEAR. Second, before installing a package, it's wise to ensure the package list is up to date. Typically, this is done by running the command apt-get update. Example #1 Debian Install Example with Apache 2 # apt-get install php5-common libapache2-mod-php5 php5-cli APT will automatically install the PHP 5 module for Apache 2 and all of its dependencies, and then activate it. Apache should be restarted in order for the changes take place. For example: Example #2 Stopping and starting Apache once PHP is installed # /etc/init.d/apache2 stop # /etc/init.d/apache2 start Better control of configuration In the last section, PHP was installed with only core modules. It's very likely that additional modules will be desired, such as MySQL, cURL, GD, etc. These may also be installed via the apt-get command. Example #3 Methods for listing additional PHP 5 packages # apt-cache search php5 # aptitude search php5 # aptitude search php5 |grep -i mysql The examples will show a lot of packages including several PHP specific ones like php5-cgi, php5-cli and php5-dev. Determine which are needed and install them like any other with either apt-get or aptitude. And because Debian performs dependency checks, it'll prompt for those so for example to install MySQL and cURL: Example #4 Install PHP with MySQL, cURL # apt-get install php5-mysql php5-curl APT will automatically add the appropriate lines to the different php.ini related files like /etc/php5/apache2/php.ini, /etc/php5/conf.d/pdo.ini, etc. and depending on the extension will add entries similar to extension=foo.so. However, restarting the web server (like Apache) is required before these changes take affect. Common Problems * If the PHP scripts are not parsing via the web server, then it's likely that PHP was not added to the web server's configuration file, which on Debian may be /etc/apache2/apache2.conf or similar. See the Debian manual for further details. * If an extension was seemingly installed yet the functions are undefined, be sure that the appropriate ini file is being loaded and/or the web server was restarted after installation. * There are two basic commands for installing packages on Debian (and other linux variants): apt-get and aptitude. However, explaining the subtle differences between these commands goes beyond the scope of this manual. ---------------------------------------------------------------------- ---------------------------------------------------------------------- ---------------------------------------------------------------------- Installation on Mac OS X Table of Contents * Using Packages * Using the bundled PHP * Compiling PHP on Mac OS X This section contains notes and hints specific to installing PHP on Mac OS X. PHP is bundled with Macs, and compiling is similar to the Unix installation guide. ---------------------------------------------------------------------- Using Packages There are a few pre-packaged and pre-compiled versions of PHP for Mac OS X. This can help in setting up a standard configuration, but if you need to have a different set of features (such as a secure server, or a different database driver), you may need to build PHP and/or your web server yourself. If you are unfamiliar with building and compiling your own software, it's worth checking whether somebody has already built a packaged version of PHP with the features you need. The following resources offer easy to install packages and precompiled binaries for PHP on Mac OS: * MacPorts: >> http://www.macports.org/ * Entropy: >> http://www.entropy.ch/software/macosx/php/ * Fink: >> http://www.finkproject.org/ * Homebrew: >> http://github.com/mxcl/homebrew ---------------------------------------------------------------------- ---------------------------------------------------------------------- Using the bundled PHP PHP has come standard with Macs since OS X version 10.0.0. Enabling PHP with the default web server requires uncommenting a few lines in the Apache configuration file httpd.conf whereas the CGI and/or CLI are enabled by default (easily accessible via the Terminal program). Enabling PHP using the instructions below is meant for quickly setting up a local development environment. It's highly recommended to always upgrade PHP to the newest version. Like most live software, newer versions are created to fix bugs and add features and PHP being is no different. See the appropriate MAC OS X installation documentation for further details. The following instructions are geared towards a beginner with details provided for getting a default setup to work. All users are encouraged to compile, or install a new packaged version. The standard installation type is using mod_php, and enabling the bundled mod_php on Mac OS X for the Apache web server (the default web server, that is accessible via System Preferences) involves the following steps: 1. Locate and open the Apache configuration file. By default, the location is as follows: /private/etc/apache2/httpd.conf Using Finder or Spotlight to find this file may prove difficult as by default it's private and owned by the root user. Note: One way to open this is by using a Unix based text editor in the Terminal, for example nano, and because the file is owned by root we'll use the sudo command to open it (as root) so for example type the following into the Terminal Application (after, it will prompt for a password): sudo nano /private/etc/apache2/httpd.conf Noteworthy nano commands: ^w (search), ^o (save), and ^x (exit) where ^ represents the Ctrl key. Note: Versions of Mac OS X prior to 10.5 were bundled with older versions of PHP and Apache. As such, the Apache configuration file on legacy machines may be /etc/httpd/httpd.conf. 2. With a text editor, uncomment the lines (by removing the #) that look similar to the following (these two lines are often not together, locate them both in the file): # LoadModule php5_module libexec/httpd/libphp5.so # AddModule mod_php5.c Notice the location/path. When building PHP in the future, the above files should be replaced or commented out. 3. Be sure the desired extensions will parse as PHP (examples: .php .html and .inc) Due to the following statement already existing in httpd.conf (as of Mac Panther), once PHP is enabled the .php files will automatically parse as PHP. # If php is turned on, we respect .php and .phps files. AddType application/x-httpd-php .php AddType application/x-httpd-php-source .phps # Since most users will want index.php to work we # also automatically enable index.php DirectoryIndex index.html index.php Note: Before OS X 10.5 (Leopard), PHP 4 was bundled instead of PHP 5 in which case the above instructions will differ slightly by changing 5's to 4's. 4. Be sure the DirectoryIndex loads the desired default index file This is also set in httpd.conf. Typically index.php and index.html are used. By default index.php is enabled because it's also in the PHP check shown above. Adjust accordingly. 5. Set the php.ini location or use the default A typical default location on Mac OS X is /usr/local/php/php.ini and a call to phpinfo() will reveal this information. If a php.ini is not used, PHP will use all default values. See also the related FAQ on finding php.ini. 6. Locate or set the DocumentRoot This is the root directory for all the web files. Files in this directory are served from the web server so the PHP files will parse as PHP before outputting them to the browser. A typical default path is /Library/WebServer/Documents but this can be set to anything in httpd.conf. Alternatively, the default DocumentRoot for individual users is /Users/yourusername/Sites 7. Create a phpinfo() file The phpinfo() function will display information about PHP. Consider creating a file in the DocumentRoot with the following PHP code: 8. Restart Apache, and load the PHP file created above To restart, either execute sudo apachectl graceful in the shell or stop/start the "Personal Web Server" option in the OS X System Preferences. By default, loading local files in the browser will have an URL like so: http://localhost/info.php Or using the DocumentRoot in the user directory is another option and would end up looking like: http://localhost/~yourusername/info.php The CLI (or CGI in older versions) is appropriately named php and likely exists as /usr/bin/php. Open up the terminal, read the command line section of the PHP manual, and execute php -v to check the PHP version of this PHP binary. A call to phpinfo() will also reveal this information. ---------------------------------------------------------------------- ---------------------------------------------------------------------- Compiling PHP on Mac OS X Use the Unix installation guide to compile PHP on Mac OS X. ---------------------------------------------------------------------- ---------------------------------------------------------------------- ---------------------------------------------------------------------- Installation on Windows systems Table of Contents * Windows Installer (PHP 5.1.0 and earlier) * Windows Installer (PHP 5.2 and later) * Manual Installation Steps * ActiveScript * Microsoft IIS * Microsoft IIS 5.1 and IIS 6.0 * Microsoft IIS 7.0 and later * Apache 1.3.x on Microsoft Windows * Apache 2.x on Microsoft Windows * Sun, iPlanet and Netscape servers on Microsoft Windows * OmniHTTPd Server * Sambar Server on Microsoft Windows * Xitami on Microsoft Windows * Building from source * Installation of extensions on Windows * Command Line PHP on Microsoft Windows This section applies to Windows 98/Me and Windows NT/2000/XP/2003. PHP will not work on 16 bit platforms such as Windows 3.1 and sometimes we refer to the supported Windows platforms as Win32. Note: Windows 98/Me/NT4 is no longer supported as of PHP 5.3.0. Note: Windows 95 is no longer supported as of PHP 4.3.0. There are two main ways to install PHP for Windows: either manually or by using the installer. If you have a development environment such as Microsoft Visual Studio, you can also build PHP from the original source code. Once you have PHP installed on your Windows system, you may also want to load various extensions for added functionality. Warning There are several all-in-one installers over the Internet, but none of those are endorsed by PHP.net, as we believe that using one of the official Windows packages from >> http://www.php.net/downloads.php is the best choice to have your system secure and optimized. ---------------------------------------------------------------------- Windows Installer (PHP 5.1.0 and earlier) The Windows PHP installer is available from the downloads page at >> http://www.php.net/downloads.php. This installs the CGI version of PHP and for IIS, PWS, and Xitami, it configures the web server as well. The installer does not include any extra external PHP extensions (php_*.dll) as you'll only find those in the Windows Zip Package and PECL downloads. Note: While the Windows installer is an easy way to make PHP work, it is restricted in many aspects as, for example, the automatic setup of extensions is not supported. Use of the installer isn't the preferred method for installing PHP. First, install your selected HTTP (web) server on your system, and make sure that it works. Run the executable installer and follow the instructions provided by the installation wizard. Two types of installation are supported - standard, which provides sensible defaults for all the settings it can, and advanced, which asks questions as it goes along. The installation wizard gathers enough information to set up the php.ini file, and configure certain web servers to use PHP. One of the web servers the PHP installer does not configure for is Apache, so you'll need to configure it manually. Once the installation has completed, the installer will inform you if you need to restart your system, restart the server, or just start using PHP. Warning Be aware, that this setup of PHP is not secure. If you would like to have a secure PHP setup, you'd better go on the manual way, and set every option carefully. This automatically working setup gives you an instantly working PHP installation, but it is not meant to be used on online servers. ---------------------------------------------------------------------- ---------------------------------------------------------------------- Windows Installer (PHP 5.2 and later) The Windows PHP installer for later versions of PHP is built using MSI technology using the Wix Toolkit (>> http://wix.sourceforge.net/). It will install and configure PHP and all the built-in and PECL extensions, as well as configure many of the popular web servers such as IIS, Apache, and Xitami. First, install your selected HTTP (web) server on your system, and make sure that it works. Then proceed with one of the following install types. Normal Install Run the MSI installer and follow the instructions provided by the installation wizard. You will be prompted to select the Web Server you wish to configure first, along with any configuration details needed. You will then be prompted to select which features and extensions you wish to install and enable. By selecting "Will be installed on local hard drive" in the drop-down menu for each item you can trigger whether to install the feature or not. By selecting "Entire feature will be installed on local hard drive", you will be able to install all sub-features of the included feature (for example by selecting this option for the feature "PDO" you will install all PDO Drivers). Warning It is not recommended to install all extensions by default, since many of them require dependencies from outside PHP in order to function properly. Instead, use the Installation Repair Mode that can be triggered thru the 'Add/Remove Programs' control panel to enable or disable extensions and features after installation. The installer then sets up PHP to be used in Windows and the php.ini file, and configures certain web servers to use PHP. The installer will currently configure IIS, Apache, Xitami, and Sambar Server; if you are using a different web server you'll need to configure it manually. Silent Install The installer also supports a silent mode, which is helpful for Systems Administrators to deploy PHP easily. To use silent mode: msiexec.exe /i php-VERSION-win32-install.msi /q You can control the install directory by passing it as a parameter to the install. For example, to install to e:\php: msiexec.exe /i php-VERSION-win32-install.msi /q INSTALLDIR=e:\php You can also use the same syntax to specify the Apache Configuration Directory (APACHEDIR), the Sambar Server directory (SAMBARDIR), and the Xitami Server directory (XITAMIDIR). You can also specify what features to install. For example, to install the mysqli extension and the CGI executable: msiexec.exe /i php-VERSION-win32-install.msi /q ADDLOCAL=cgi,ext_php_mysqli The current list of Features to install is as follows: MainExecutable - php.exe executable ( no longer available as of PHP 5.2.10/5.3.0; it is now included by default ) ScriptExecutable - php-win.exe executable ext_php_* - the various extensions ( for example: ext_php_mysql for MySQL ) apache13 - Apache 1.3 module apache20 - Apache 2.0 module apache22 - Apache 2.2 module apacheCGI - Apache CGI executable iis4ISAPI - IIS ISAPI module iis4CGI - IIS CGI executable iis4FastCGI - IIS CGI executable NSAPI - Sun/iPlanet/Netscape server module netserve - NetServe Web Server CGI executable Xitami - Xitami CGI executable Sambar - Sambar Server ISAPI module CGI - php-cgi.exe executable PEAR - PEAR installer Manual - PHP Manual in CHM Format For more information on installing MSI installers from the command line, visit >> http://msdn.microsoft.com/en-us/library/aa367988.aspx Upgrading PHP with the Install To upgrade, run the installer either graphically or from the command line as normal. The installer will read your current install options, remove your old installation, and reinstall PHP with the same options as before. It is recommended that you use this method of keeping PHP updated instead of manually replacing the files in the installation directory. ---------------------------------------------------------------------- ---------------------------------------------------------------------- Manual Installation Steps This section contains instructions for manually installing and configuring PHP on Microsoft Windows. For the instructions on how to use PHP installer to setup and configure PHP and a web server on Windows refer to Windows Installer (PHP 5.2 and later). Selecting and downloading the PHP distribution package Download the PHP zip binary distribution from >> PHP for Windows: Binaries and Sources. There are several different versions of the zip package - chose the version that is suitable for the web server being used: * If PHP is used with IIS then choose PHP 5.3 VC9 Non Thread Safe or PHP 5.2 VC6 Non Thread Safe; * If PHP is used with IIS7 or greater and PHP 5.3+, then the VC9 binaries of PHP should be used. * If PHP is used with Apache 1 or Apache 2 then choose PHP 5.3 VC6 or PHP 5.2 VC6. Note: VC9 Versions are compiled with the Visual Studio 2008 compiler and have improvements in performance and stability. The VC9 versions require you to have the >> Microsoft 2008 C++ Runtime (x86) or the >> Microsoft 2008 C++ Runtime (x64) installed. The PHP package structure and content Unpack the content of the zip archive into a directory of your choice, for example C:\PHP\. The directory and file structure extracted from the zip will look as below: Example #1 PHP 5 package structure c:\php | +--dev | | | |-php5ts.lib -- php5.lib in non thread safe version | +--ext -- extension DLLs for PHP | | | |-php_bz2.dll | | | |-php_cpdf.dll | | | |-... | +--extras -- empty | +--pear -- initial copy of PEAR | | |-go-pear.bat -- PEAR setup script | |-... | |-php-cgi.exe -- CGI executable | |-php-win.exe -- executes scripts without an opened command prompt | |-php.exe -- Command line PHP executable (CLI) | |-... | |-php.ini-development -- default php.ini settings | |-php.ini-production -- recommended php.ini settings | |-php5apache2_2.dll -- does not exist in non thread safe version | |-php5apache2_2_filter.dll -- does not exist in non thread safe version | |-... | |-php5ts.dll -- core PHP DLL ( php5.dll in non thread safe version) | |-... Below is the list of the modules and executables included in the PHP zip distribution: * go-pear.bat - the PEAR setup script. Refer to >> Installation (PEAR) for more details. * php-cgi.exe - CGI executable that can be used when running PHP on IIS via CGI or FastCGI. * php-win.exe - the PHP executable for executing PHP scripts without using a command line window (for example PHP applications that use Windows GUI). * php.exe - the PHP executable for executing PHP scripts within a command line interface (CLI). * php5apache2_2.dll - Apache 2.2.X module. * php5apache2_2_filter.dll - Apache 2.2.X filter. Changing the php.ini file After the php package content has been extracted, copy the php.ini-production into php.ini in the same folder. If necessary, it is also possible to place the php.ini into any other location of your choice but that will require additional configuration steps as described in PHP Configuration. The php.ini file tells PHP how to configure itself, and how to work with the environment that it runs in. Here are a number of settings for the php.ini file that help PHP work better with Windows. Some of these are optional. There are many other directives that may be relevant to your environment - refer to the list of php.ini directives for more information. Required directives: * extension_dir = - The extension_dir needs to point to the directory where PHP extensions files are stored. The path can be absolute (i.e. "C:\PHP\ext") or relative (i.e. ".\ext"). Extensions that are listed lower in the php.ini file need to be located in the extension_dir. * extension = xxxxx.dll - For each extension you wish to enable, you need a corresponding "extension=" directive that tells PHP which extensions in the extension_dir to load at startup time. * log_errors = On - PHP has an error logging facility that can be used to send errors to a file, or to a service (i.e. syslog) and works in conjunction with the error_log directive below. When running under IIS, the log_errors should be enabled, with a valid error_log. * error_log = - The error_log needs to specify the absolute, or relative path to the file where PHP errors should be logged. This file needs to be writable for the web server. The most common places for this file are in various TEMP directories, for example "C:\inetpub\temp\php-errors.log". * cgi.force_redirect = 0 - This directive is required for running under IIS. It is a directory security facility required by many other web servers. However, enabling it under IIS will cause the PHP engine to fail on Windows. * cgi.fix_pathinfo = 1 - This lets PHP access real path info following the CGI Spec. The IIS FastCGI implementation needs this set. * fastcgi.impersonate = 1 - FastCGI under IIS supports the ability to impersonate security tokens of the calling client. This allows IIS to define the security context that the request runs under. * fastcgi.logging = 0 - FastCGI logging should be disabled on IIS. If it is left enabled, then any messages of any class are treated by FastCGI as error conditions which will cause IIS to generate an HTTP 500 exception. Optional directives * max_execution_time = ## - This directive tells PHP the maximum amount of time that it can spend executing any given script. The default for this is 30 seconds. Increase the value of this directive if PHP application take long time to execute. * memory_limit = ###M - The amount of memory available for the PHP process, in Megabytes. The default is 128, which is fine for most PHP applications. Some of the more complex ones might need more. * display_errors = Off - This directive tells PHP whether to include any error messages in the stream that it returns to the Web server. If this is set to "On", then PHP will send whichever classes of errors that you define with the error_reporting directive back to web server as part of the error stream. For security reasons it is recommended to set it to "Off" on production servers in order not to reveal any security sensitive information that is often included in the error messages. * open_basedir = , e.g. openbasedir="C:\inetpub\wwwroot;C:\inetpub\temp". This directive specified the directory paths where PHP is allowed to perform file system operations. Any file operation outside of the specified paths will result in an error. This directive is especially useful for locking down the PHP installation in shared hosting environments to prevent PHP scripts from accessing any files outside of the web site's root directory. * upload_max_filesize = ###M and post_max_size = ###M - The maximum allowed size of an uploaded file and post data respectively. The values of these directives should be increased if PHP applications need to perform large uploads, such as for example photos or video files. PHP is now setup on your system. The next step is to choose a web server, and enable it to run PHP. Choose a web server from the table of contents. In addition to running PHP via a web server, PHP can run from the command line just like a .BAT script. See Command Line PHP on Microsoft Windows for further details. ---------------------------------------------------------------------- ---------------------------------------------------------------------- ActiveScript This section contains notes specific to the ActiveScript installation. ActiveScript is a Windows only SAPI that enables you to use PHP script in any ActiveScript compliant host, like Windows Script Host, ASP/ASP.NET, Windows Script Components or Microsoft Scriptlet control. As of PHP 5.0.1, ActiveScript has been moved to the >> PECL repository. A DLL for this PECL extension is currently unavailable. See also the building on Windows section. Note: You should read the manual installation steps first! After installing PHP, you should download the ActiveScript DLL (php5activescript.dll) and place it in the main PHP folder (e.g. C:\php). After having all the files needed, you must register the DLL on your system. To achieve this, open a Command Prompt window (located in the Start Menu). Then go to your PHP directory by typing something like cd C:\php. To register the DLL just type regsvr32 php5activescript.dll. To test if ActiveScript is working, create a new file, named test.wsf (the extension is very important) and type: Save and double-click on the file. If you receive a little window saying "Hello World!" you're done. Note: In PHP 4, the engine was named 'ActivePHP', so if you are using PHP 4, you should replace 'PHPScript' with 'ActivePHP' in the above example. Note: ActiveScript doesn't use the default php.ini file. Instead, it will look only in the same directory as the .exe that caused it to load. You should create php-activescript.ini and place it in that folder, if you wish to load extensions, etc. ---------------------------------------------------------------------- ---------------------------------------------------------------------- Microsoft IIS This section contains PHP installation instructions specific to Microsoft Internet Information Services (IIS). * Manually installing PHP on Microsoft IIS 5.1 and IIS 6.0 * Manually installing PHP on Microsoft IIS 7.0 and later ---------------------------------------------------------------------- ---------------------------------------------------------------------- Microsoft IIS 5.1 and IIS 6.0 This section contains instructions for manually setting up Internet Information Services (IIS) 5.1 and IIS 6.0 to work with PHP on Microsoft Windows XP and Windows Server 2003. For instructions on setting up IIS 7.0 and later versions on Windows Vista, Windows Server 2008, Windows 7 and Windows Server 2008 R2 refer to Microsoft IIS 7.0 and later. Configuring IIS to process PHP requests Download and install PHP in accordance to the instructions described in manual installation steps Note: Non-thread-safe build of PHP is recommended when using IIS. The non-thread-safe builds are available at >> PHP for Windows: Binaries and Sources Releases. Configure the CGI- and FastCGI-specific settings in php.ini file as shown below: Example #1 CGI and FastCGI settings in php.ini fastcgi.impersonate = 1 fastcgi.logging = 0 cgi.fix_pathinfo=1 cgi.force_redirect = 0 Download and install the >> Microsoft FastCGI Extension for IIS 5.1 and 6.0. The extension is available for 32-bit and 64-bit platforms - select the right download package for your platform. Configure the FastCGI extension to handle PHP-specific requests by running the command shown below. Replace the value of the "-path" parameter with the absolute file path to the php-cgi.exe file. Example #2 Configuring FastCGI extension to handle PHP requests cscript %windir%\system32\inetsrv\fcgiconfig.js -add -section:"PHP" ^ -extension:php -path:"C:\PHP\php-cgi.exe" This command will create an IIS script mapping for *.php file extension, which will result in all URLs that end with .php being handled by FastCGI extension. Also, it will configure FastCGI extension to use the executable php-cgi.exe to process the PHP requests. Note: At this point the required installation and configuration steps are completed. The remaining instructions below are optional but highly recommended for achieving optimal functionality and performance of PHP on IIS. Impersonation and file system access It is recommended to enable FastCGI impersonation in PHP when using IIS. This is controlled by the fastcgi.impersonate directive in php.ini file. When impersonation is enabled, PHP will perform all the file system operations on behalf of the user account that has been determined by IIS authentication. This ensures that even if the same PHP process is shared across different IIS web sites, the PHP scripts in those web sites will not be able to access each others' files as long as different user accounts are used for IIS authentication on each web site. For example IIS 5.1 and IIS 6.0, in its default configuration, has anonymous authentication enabled with built-in user account IUSR_ used as a default identity. This means that in order for IIS to execute PHP scripts, it is necessary to grant IUSR_ account read permission on those scripts. If PHP applications need to perform write operations on certain files or write files into some folders then IUSR_ account should have write permission to those. To determine which user account is used by IIS anonymous authentication, follow these steps: 1. In the Windows Start Menu choose "Run:", type "inetmgr" and click "Ok"; 2. Expand the list of web sites under the "Web Sites" node in the tree view, right-click on a web site that is being used and select "Properties"; 3. Click the "Directory Security" tab; 4. Take note of a "User name:" field in the "Authentication Methods" dialog Anonymous authenication for IIS 5.1 and IIS 6.0 To modify the permissions settings on files and folders, use the Windows Explorer user interface or icacls command. Example #3 Configuring file access permissions icacls C:\inetpub\wwwroot\upload /grant IUSR:(OI)(CI)(M) Set index.php as a default document in IIS The IIS default documents are used for HTTP requests that do not specify a document name. With PHP applications, index.php usually acts as a default document. To add index.php to the list of IIS default documents, follow these steps: 1. In the Windows Start Menu choose "Run:", type "inetmgr" and click "Ok"; 2. Right-click on the "Web Sites" node in the tree view and select "Properties"; 3. Click the "Documents" tab; 4. Click the "Add..." button and enter "index.php" for the "Default content page:". Setting index.php as default document for IIS FastCGI and PHP Recycling configuration Configure IIS FastCGI extension settings for recycling of PHP processes by using the commands shown below. The FastCGI setting instanceMaxRequests controls how many requests will be processed by a single php-cgi.exe process before FastCGI extension shuts it down. The PHP environment variable PHP_FCGI_MAX_REQUESTS controls how many requests a single php-cgi.exe process will handle before it recycles itself. Make sure that the value specified for FastCGI InstanceMaxRequests setting is less than or equal to the value specified for PHP_FCGI_MAX_REQUESTS. Example #4 Configuring FastCGI and PHP recycling cscript %windir%\system32\inetsrv\fcgiconfig.js -set -section:"PHP" ^ -InstanceMaxRequests:10000 cscript %windir%\system32\inetsrv\fcgiconfig.js -set -section:"PHP" ^ -EnvironmentVars:PHP_FCGI_MAX_REQUESTS:10000 Configuring FastCGI timeout settings Increase the timeout settings for FastCGI extension if there are applications that have long running PHP scripts. The two settings that control timeouts are ActivityTimeout and RequestTimeout. Refer to >> Configuring FastCGI Extension for IIS 6.0 for more information about those settings. Example #5 Configuring FastCGI timeout settings cscript %windir%\system32\inetsrv\fcgiconfig.js -set -section:"PHP" ^ -ActivityTimeout:90 cscript %windir%\system32\inetsrv\fcgiconfig.js -set -section:"PHP" ^ -RequestTimeout:90 Changing the Location of php.ini file PHP searches for php.ini file in several locations and it is possible to change the default locations of php.ini file by using PHPRC environment variable. To instruct PHP to load the configuration file from a custom location run the command shown below. The absolute path to the directory with php.ini file should be specified as a value of PHPRC environment variable. Example #6 Changing the location of php.ini file cscript %windir%\system32\inetsrv\fcgiconfig.js -set -section:"PHP" ^ -EnvironmentVars:PHPRC:"C:\Some\Directory\" ---------------------------------------------------------------------- ---------------------------------------------------------------------- Microsoft IIS 7.0 and later This section contains instructions for manually setting up Internet Information Services (IIS) 7.0 and later to work with PHP on Microsoft Windows Vista SP1, Windows 7, Windows Server 2008 and Windows Server 2008 R2. For instructions on setting up IIS 5.1 and IIS 6.0 on Windows XP and Windows Server 2003 refer to Microsoft IIS 5.1 and IIS 6.0. Enabling FastCGI support in IIS FastCGI module is disabled in default installation of IIS. The steps to enable it differ based on the version of Windows being used. To enable FastCGI support on Windows Vista SP1 and Windows 7: 1. In the Windows Start Menu choose "Run:", type "optionalfeatures.exe" and click "Ok"; 2. In the "Windows Features" dialog expand "Internet Information Services", "World Wide Web Services", "Application Development Features" and then enable the "CGI" checkbox; 3. Click OK and wait until the installation is complete. Enabling FastCGI support for IIS7 on Windows Vista SP1 and Windows 7 To enable FastCGI support on Windows Server 2008 and Windows Server 2008 R2: 1. In the Windows Start Menu choose "Run:", type "CompMgmtLauncher" and click "Ok"; 2. If the "Web Server (IIS)" role is not present under the "Roles" node, then add it by clicking "Add Roles"; 3. If the "Web Server (IIS)" role is present, then click "Add Role Services" and then enable the "CGI" checkbox under "Application Development" group; 4. Click "Next" and then "Install" and wait for the installation to complete. Enabling FastCGI support on Windows Server 2008 and Windows Server 2008 R2 Configuring IIS to process PHP requests Download and install PHP in accordance to the instructions described in manual installation steps Note: Non-thread-safe build of PHP is recommended when using IIS. The non-thread-safe builds are available at >> PHP for Windows: Binaries and Sources Releases. Configure the CGI- and FastCGI-specific settings in php.ini file as shown below: Example #1 CGI and FastCGI settings in php.ini fastcgi.impersonate = 1 fastcgi.logging = 0 cgi.fix_pathinfo=1 cgi.force_redirect = 0 Configure IIS handler mapping for PHP by using either IIS Manager user interface or a command line tool. Using IIS Manager user interface to create a handler mapping for PHP Follow these steps to create an IIS handler mapping for PHP in IIS Manager user interface: 1. In the Windows Start Menu choose "Run:", type "inetmgr" and click "Ok"; 2. In the IIS Manager user interface select the server node in the "Connections" tree view; 3. In the "Features View" page open the "Handler Mappings" feature; Create IIS handler mapping for PHP : Locate Handler Mappings 4. In the "Actions" pane click "Add Module Mapping..."; 5. In the "Add Module Mapping" dialog enter the following: * Request path: *.php * Module: FastCgiModule * Executable: C:\[Path to PHP installation]\php-cgi.exe * Name: PHP_via_FastCGI 6. Click "Request Restrictions" button and then configure the mapping to invoke handler only if request is mapped to a file or a folder; 7. Click OK on all the dialogs to save the configuration. Create IIS handler mapping for PHP : Add Handler Mapping Using command line tool to create a handler mapping for PHP Use the command shown below to create an IIS FastCGI process pool which will use php-cgi.exe executable for processing PHP requests. Replace the value of the fullPath parameter with the absolute file path to the php-cgi.exe file. Example #2 Creating IIS FastCGI process pool %windir%\system32\inetsrv\appcmd set config /section:system.webServer/fastCGI ^ /+[fullPath='c:\PHP\php-cgi.exe'] Configure IIS to handle PHP specific requests by running the command shown below. Replace the value of the scriptProcessor parameter with the absolute file path to the php-cgi.exe file. Example #3 Creating handler mapping for PHP requests %windir%\system32\inetsrv\appcmd set config /section:system.webServer/handlers ^ /+[name='PHP_via_FastCGI', path='*.php',verb='*',modules='FastCgiModule',^ scriptProcessor='c:\PHP\php-cgi.exe',resourceType='Either'] This command creates an IIS handler mapping for *.php file extension, which will result in all URLs that end with .php being handled by FastCGI module. Note: At this point the required installation and configuration steps are completed. The remaining instructions below are optional but highly recommended for achieving optimal functionality and performance of PHP on IIS. Impersonation and file system access It is recommended to enable FastCGI impersonation in PHP when using IIS. This is controlled by the fastcgi.impersonate directive in php.ini file. When impersonation is enabled, PHP will perform all the file system operations on behalf of the user account that has been determined by IIS authentication. This ensures that even if the same PHP process is shared across different IIS web sites, the PHP scripts in those web sites will not be able to access each other's files as long as different user accounts are used for IIS authentication on each web site. For example IIS 7, in its default configuration, has anonymous authentication enabled with built-in user account IUSR used as a default identity. This means that in order for IIS to execute PHP scripts, it is necessary to grant IUSR account read permission on those scripts. If PHP applications need to perform write operations on certain files or write files into some folders then IUSR account should have write permission to those. To determine what user account is used as an anonymous identity in IIS 7 use the following command. Replace the "Default Web Site" with the name of IIS web site that you use. In the output XML configuration element look for the userName attribute. Example #4 Determining the account used as IIS anonymous identity %windir%\system32\inetsrv\appcmd.exe list config "Default Web Site" ^ /section:anonymousAuthentication Note: If userName attribute is not present in the anonymousAuthentication element, or is set to an empty string, then it means that the application pool identity is used as an anonymous identity for that web site. To modify the permissions settings on files and folders, use the Windows Explorer user interface or icacls command. Example #5 Configuring file access permissions icacls C:\inetpub\wwwroot\upload /grant IUSR:(OI)(CI)(M) Set index.php as a default document in IIS The IIS default documents are used for HTTP requests that do not specify a document name. With PHP applications, index.php usually acts as a default document. To add index.php to the list of IIS default documents, use this command: Example #6 Set index.php as a default document in IIS %windir%\system32\inetsrv\appcmd.exe set config ^ -section:system.webServer/defaultDocument /+"files.[value='index.php']" ^ /commit:apphost FastCGI and PHP Recycling configuration Configure IIS FastCGI settings for recycling of PHP processes by using the commands shown below. The FastCGI setting instanceMaxRequests controls how many requests will be processed by a single php-cgi.exe process before IIS shuts it down. The PHP environment variable PHP_FCGI_MAX_REQUESTS controls how many requests a single php-cgi.exe process will handle before it recycles itself. Make sure that the value specified for FastCGI InstanceMaxRequests setting is less than or equal to the value specified for PHP_FCGI_MAX_REQUESTS. Example #7 Configuring FastCGI and PHP recycling %windir%\system32\inetsrv\appcmd.exe set config -section:system.webServer/fastCgi ^ /[fullPath='c:\php\php-cgi.exe'].instanceMaxRequests:10000 %windir%\system32\inetsrv\appcmd.exe set config -section:system.webServer/fastCgi ^ /+"[fullPath='C:\{php_folder}\php-cgi.exe'].environmentVariables.^ [name='PHP_FCGI_MAX_REQUESTS',value='10000']" FastCGI timeout settings Increase the timeout settings for FastCGI if it is expected to have long running PHP scripts. The two settings that control timeouts are activityTimeout and requestTimeout. Use the commands below to change the timeout settings. Make sure to replace the value in the fullPath parameter to contain the absolute path to the php-cgi.exe file. Example #8 Configuring FastCGI timeout settings %windir%\system32\inetsrv\appcmd.exe set config -section:system.webServer/fastCgi ^ /[fullPath='C:\php\php-cgi.exe',arguments=''].activityTimeout:"90" /commit:apphost %windir%\system32\inetsrv\appcmd.exe set config -section:system.webServer/fastCgi ^ /[fullPath='C:\php\php-cgi.exe',arguments=''].requestTimeout:"90" /commit:apphost Changing the Location of php.ini file PHP searches for php.ini file in several locations and it is possible to change the default locations of php.ini file by using PHPRC environment variable. To instruct PHP to load the configuration file from a custom location run the command shown below. The absolute path to the directory with php.ini file should be specified as a value of PHPRC environment variable. Example #9 Changing the location of php.ini file appcmd.exe set config -section:system.webServer/fastCgi ^ /+"[fullPath='C:\php\php.exe',arguments=''].environmentVariables.^ [name='PHPRC',value='C:\Some\Directory\']" /commit:apphost ---------------------------------------------------------------------- ---------------------------------------------------------------------- Apache 1.3.x on Microsoft Windows This section contains notes and hints specific to Apache 1.3.x installs of PHP on Microsoft Windows systems. There are also instructions and notes for Apache 2 on a separate page. Note: Please read the manual installation steps first! There are two ways to set up PHP to work with Apache 1.3.x on Windows. One is to use the CGI binary (php.exe for PHP 4 and php-cgi.exe for PHP 5), the other is to use the Apache Module DLL. In either case you need to edit your httpd.conf to configure Apache to work with PHP, and then restart the server. It is worth noting here that now the SAPI module has been made more stable under Windows, we recommend it's use above the CGI binary, since it is more transparent and secure. Although there can be a few variations of configuring PHP under Apache, these are simple enough to be used by the newcomer. Please consult the Apache Documentation for further configuration directives. After changing the configuration file, remember to restart the server, for example, NET STOP APACHE followed by NET START APACHE, if you run Apache as a Windows Service, or use your regular shortcuts. Note: Remember that when adding path values in the Apache configuration files on Windows, all backslashes such as c:\directory\file.ext should be converted to forward slashes: c:/directory/file.ext. A trailing slash may also be necessary for directories. Installing as an Apache module You should add the following lines to your Apache httpd.conf file: Example #1 PHP as an Apache 1.3.x module This assumes PHP is installed to c:\php. Adjust the path if this is not the case. For PHP 4: # Add to the end of the LoadModule section # Don't forget to copy this file from the sapi directory! LoadModule php4_module "C:/php/php4apache.dll" # Add to the end of the AddModule section AddModule mod_php4.c For PHP 5: # Add to the end of the LoadModule section LoadModule php5_module "C:/php/php5apache.dll" # Add to the end of the AddModule section AddModule mod_php5.c For both: # Add this line inside the conditional brace AddType application/x-httpd-php .php # For syntax highlighted .phps files, also add AddType application/x-httpd-php-source .phps Installing as a CGI binary If you unzipped the PHP package to C:\php\ as described in the Manual Installation Steps section, you need to insert these lines to your Apache configuration file to set up the CGI binary: Example #2 PHP and Apache 1.3.x as CGI ScriptAlias /php/ "c:/php/" AddType application/x-httpd-php .php # For PHP 4 Action application/x-httpd-php "/php/php.exe" # For PHP 5 Action application/x-httpd-php "/php/php-cgi.exe" # specify the directory where php.ini is SetEnv PHPRC C:/php Note that the second line in the list above can be found in the actual versions of httpd.conf, but it is commented out. Remember also to substitute the c:/php/ for your actual path to PHP. Warning A server deployed in CGI mode is open to several possible vulnerabilities. Please read our CGI security section to learn how to defend yourself from such attacks. If you would like to present PHP source files syntax highlighted, there is no such convenient option as with the module version of PHP. If you chose to configure Apache to use PHP as a CGI binary, you will need to use the highlight_file() function. To do this simply create a PHP script file and add this code: . ---------------------------------------------------------------------- ---------------------------------------------------------------------- Apache 2.x on Microsoft Windows This section contains notes and hints specific to Apache 2.x installs of PHP on Microsoft Windows systems. We also have instructions and notes for Apache 1.3.x users on a separate page. Note: You should read the manual installation steps first! Note: Apache 2.2 Support Users of Apache 2.2 should note that the DLL file for Apache 2.2 is named php5apache2_2.dll rather than php5apache2.dll and is available only for PHP 5.2.0 and later. See also >> http://snaps.php.net/ You are strongly encouraged to consult the >> Apache Documentation to get a basic understanding of the Apache 2.x Server. Also consider reading the >> Windows specific notes for Apache 2.x before reading on here. Apache 2.x is designed to run on the Windows version designated as server platforms, such as Windows NT 4.0, Windows 2000, Windows XP, or Windows 7. While Apache 2.x works tolerably well on Windows 9x, support on these platforms is incomplete, and some things will not work correctly. There is no plan to remedy this situation. Download the most recent version of >> Apache 2.x and a fitting PHP version. Follow the Manual Installation Steps and come back to go on with the integration of PHP and Apache. There are three ways to set up PHP to work with Apache 2.x on Windows. You can run PHP as a handler, as a CGI, or under FastCGI. Note: Remember that when adding path values in the Apache configuration files on Windows, all backslashes such as c:\directory\file.ext should be converted to forward slashes: c:/directory/file.ext. A trailing slash may also be necessary for directories. Installing as an Apache handler You need to insert the following lines into your Apache httpd.conf configuration file to load the PHP module for Apache 2.x: Example #1 PHP and Apache 2.x as handler # LoadModule php5_module "c:/php/php5apache2.dll" AddHandler application/x-httpd-php .php # configure the path to php.ini PHPIniDir "C:/php" Note: Remember to substitute your actual path to PHP for the C:/php/ in the above examples. Take care to use either php5apache2.dll or php5apache2_2.dll in your LoadModule directive and verify that the referenced file is in fact located at the file path that you point to in this directive. The above configuration will enable PHP handling of any file that has a .php extension, even if there are other file extensions. For example, a file named example.php.txt will be executed by the PHP handler. To ensure that only files that end in .php are executed, use the following configuration instead: SetHandler application/x-httpd-php Running PHP as CGI You should consult the >> Apache CGI documentation for a more complete understanding of running CGI on Apache. To run PHP as CGI, you'll need to place your php-cgi files in a directory designated as a CGI directory using the ScriptAlias directive. You will then need to insert a #! line in the PHP files, pointing to the location of your PHP binary: Example #2 PHP and Apache 2.x as CGI #!C:/php/php.exe Warning A server deployed in CGI mode is open to several possible vulnerabilities. Please read our CGI security section to learn how to defend yourself from such attacks. Running PHP under FastCGI Running PHP under FastCGI has a number of advantages over running it as a CGI. Setting it up this way is fairly straightforward: Obtain mod_fcgid from >> http://httpd.apache.org/mod_fcgid/. Win32 binaries are available for download from that site. Install the module according to the instructions that will come with it. Configure your web server as shown below, taking care to adjust any paths to reflect your how you have installed things on your particular system: Example #3 Configure Apache to run PHP as FastCGI LoadModule fcgid_module modules/mod_fcgid.so # Where is your php.ini file? FcgidInitialEnv PHPRC "c:/php" AddHandler fcgid-script .php FcgidWrapper "c:/php/php-cgi.exe" .php Files with a .php extension will now be executed by the PHP FastCGI wrapper. ---------------------------------------------------------------------- ---------------------------------------------------------------------- Sun, iPlanet and Netscape servers on Microsoft Windows This section contains notes and hints specific to Sun Java System Web Server, Sun ONE Web Server, iPlanet and Netscape server installs of PHP on Windows. From PHP 4.3.3 on you can use PHP scripts with the NSAPI module to generate custom directory listings and error pages. Additional functions for Apache compatibility are also available. For support in current web servers read the note about subrequests. CGI setup on Sun, iPlanet and Netscape servers To install PHP as a CGI handler, do the following: * Copy php4ts.dll to your systemroot (the directory where you installed Windows) * Make a file association from the command line. Type the following two lines: assoc .php=PHPScript ftype PHPScript=c:\php\php.exe %1 %* * In the Netscape Enterprise Administration Server create a dummy shellcgi directory and remove it just after (this step creates 5 important lines in obj.conf and allow the web server to handle shellcgi scripts). * In the Netscape Enterprise Administration Server create a new mime type (Category: type, Content-Type: magnus-internal/shellcgi, File Suffix:php). * Do it for each web server instance you want PHP to run More details about setting up PHP as a CGI executable can be found here: >> http://benoit.noss.free.fr/php/install-php.html NSAPI setup on Sun, iPlanet and Netscape servers To install PHP with NSAPI, do the following: * Copy php4ts.dll to your systemroot (the directory where you installed Windows) * Make a file association from the command line. Type the following two lines: assoc .php=PHPScript ftype PHPScript=c:\php\php.exe %1 %* * In the Netscape Enterprise Administration Server create a new mime type (Category: type, Content-Type: magnus-internal/x-httpd-php, File Suffix: php). * Edit magnus.conf (for servers >= 6) or obj.conf (for servers < 6) and add the following: You should place the lines after mime types init. Init fn="load-modules" funcs="php4_init,php4_execute,php4_auth_trans" shlib="c:/php/sapi/php4nsapi.dll" Init fn="php4_init" LateInit="yes" errorString="Failed to initialise PHP!" [php_ini="c:/path/to/php.ini"] (PHP >= 4.3.3) The php_ini parameter is optional but with it you can place your php.ini in your web server configuration directory. * Configure the default object in obj.conf (for virtual server classes [Sun Web Server 6.0+] in their vserver.obj.conf): In the section, place this line necessarily after all 'ObjectType' and before all 'AddLog' lines: Service fn="php4_execute" type="magnus-internal/x-httpd-php" [inikey=value inikey=value ...] (PHP >= 4.3.3) As additional parameters you can add some special php.ini-values, for example you can set a docroot="/path/to/docroot" specific to the context php4_execute is called. For boolean ini-keys please use 0/1 as value, not "On","Off",... (this will not work correctly), e.g. zlib.output_compression=1 instead of zlib.output_compression="On" * This is only needed if you want to configure a directory that only consists of PHP scripts (same like a cgi-bin directory): ObjectType fn="force-type" type="magnus-internal/x-httpd-php" Service fn=php4_execute [inikey=value inikey=value ...] After that you can configure a directory in the Administration server and assign it the style x-httpd-php. All files in it will get executed as PHP. This is nice to hide PHP usage by renaming files to .html. * Restart your web service and apply changes * Do it for each web server instance you want PHP to run Note: More details about setting up PHP as an NSAPI filter can be found here: >> http://benoit.noss.free.fr/php/install-php4.html Note: The stacksize that PHP uses depends on the configuration of the web server. If you get crashes with very large PHP scripts, it is recommended to raise it with the Admin Server (in the section "MAGNUS EDITOR"). CGI environment and recommended modifications in php.ini Important when writing PHP scripts is the fact that Sun JSWS/Sun ONE WS/iPlanet/Netscape is a multithreaded web server. Because of that all requests are running in the same process space (the space of the web server itself) and this space has only one environment. If you want to get CGI variables like PATH_INFO, HTTP_HOST etc. it is not the correct way to try this in the old PHP way with getenv() or a similar way (register globals to environment, $_ENV). You would only get the environment of the running web server without any valid CGI variables! Note: Why are there (invalid) CGI variables in the environment? Answer: This is because you started the web server process from the admin server which runs the startup script of the web server, you wanted to start, as a CGI script (a CGI script inside of the admin server!). This is why the environment of the started web server has some CGI environment variables in it. You can test this by starting the web server not from the administration server. Use the command line as root user and start it manually - you will see there are no CGI-like environment variables. Simply change your scripts to get CGI variables in the correct way for PHP 4.x by using the superglobal $_SERVER. If you have older scripts which use $HTTP_HOST, etc., you should turn on register_globals in php.ini and change the variable order too (important: remove "E" from it, because you do not need the environment here): variables_order = "GPCS" register_globals = On Special use for error pages or self-made directory listings (PHP >= 4.3.3) You can use PHP to generate the error pages for "404 Not Found" or similar. Add the following line to the object in obj.conf for every error page you want to overwrite: Error fn="php4_execute" code=XXX script="/path/to/script.php" [inikey=value inikey=value...] where XXX is the HTTP error code. Please delete any other Error directives which could interfere with yours. If you want to place a page for all errors that could exist, leave the code parameter out. Your script can get the HTTP status code with $_SERVER['ERROR_TYPE']. Another possibility is to generate self-made directory listings. Just create a PHP script which displays a directory listing and replace the corresponding default Service line for type="magnus-internal/directory" in obj.conf with the following: Service fn="php4_execute" type="magnus-internal/directory" script="/path/to/script.php" [inikey=value inikey=value...] For both error and directory listing pages the original URI and translated URI are in the variables $_SERVER['PATH_INFO'] and $_SERVER['PATH_TRANSLATED']. Note about nsapi_virtual() and subrequests (PHP >= 4.3.3) The NSAPI module now supports the nsapi_virtual() function (alias: virtual()) to make subrequests on the web server and insert the result in the web page. The problem is, that this function uses some undocumented features from the NSAPI library. Under Unix this is not a problem, because the module automatically looks for the needed functions and uses them if available. If not, nsapi_virtual() is disabled. Under Windows limitations in the DLL handling need the use of a automatic detection of the most recent ns-httpdXX.dll file. This is tested for servers till version 6.1. If a newer version of the Sun server is used, the detection fails and nsapi_virtual() is disabled. If this is the case, try the following: Add the following parameter to php4_init in magnus.conf/obj.conf: Init fn=php4_init ... server_lib="ns-httpdXX.dll" where XX is the correct DLL version number. To get it, look in the server-root for the correct DLL name. The DLL with the biggest filesize is the right one. You can check the status by using the phpinfo() function. Note: But be warned: Support for nsapi_virtual() is EXPERIMENTAL!!! ---------------------------------------------------------------------- ---------------------------------------------------------------------- OmniHTTPd Server This section contains notes and hints specific to >> OmniHTTPd on Windows. Note: You should read the manual installation steps first! Warning A server deployed in CGI mode is open to several possible vulnerabilities. Please read our CGI security section to learn how to defend yourself from such attacks. You need to complete the following steps to make PHP work with OmniHTTPd. This is a CGI executable setup. SAPI is supported by OmniHTTPd, but some tests have shown that it is not so stable to use PHP as an ISAPI module. Note: Important for CGI users Read the faq on cgi.force_redirect for important details. This directive needs to be set to 0. 1. Install OmniHTTPd server. 2. Right click on the blue OmniHTTPd icon in the system tray and select Properties 3. Click on Web Server Global Settings 4. On the 'External' tab, enter: virtual = .php | actual = c:\php\php.exe (use php-cgi.exe if installing PHP 5), and use the Add button. 5. On the Mime tab, enter: virtual = wwwserver/stdcgi | actual = .php, and use the Add button. 6. Click OK Repeat steps 2 - 6 for each extension you want to associate with PHP. Note: Some OmniHTTPd packages come with built in PHP support. You can choose at setup time to do a custom setup, and uncheck the PHP component. We recommend you to use the latest PHP binaries. Some OmniHTTPd servers come with PHP 4 beta distributions, so you should choose not to set up the built in support, but install your own. If the server is already on your machine, use the Replace button in Step 4 and 5 to set the new, correct information. ---------------------------------------------------------------------- ---------------------------------------------------------------------- Sambar Server on Microsoft Windows This section contains notes and hints specific to the >> Sambar Server for Windows. Note: You should read the manual installation steps first! This list describes how to set up the ISAPI module to work with the Sambar server on Windows. * Find the file called mappings.ini (in the config directory) in the Sambar install directory. * Open mappings.ini and add the following line under [ISAPI]: Example #1 ISAPI configuration of Sambar #for PHP 4 *.php = c:\php\php4isapi.dll #for PHP 5 *.php = c:\php\php5isapi.dll (This line assumes that PHP was installed in c:\php.) * Now restart the Sambar server for the changes to take effect. Note: If you intend to use PHP to communicate with resources which are held on a different computer on your network, then you will need to alter the account used by the Sambar Server Service. The default account used for the Sambar Server Service is LocalSystem which will not have access to remote resources. The account can be amended by using the Services option from within the Windows Control Panel Administation Tools. ---------------------------------------------------------------------- ---------------------------------------------------------------------- Xitami on Microsoft Windows This section contains notes and hints specific to >> Xitami on Windows. Note: You should read the manual installation steps first! This list describes how to set up the PHP CGI binary to work with Xitami on Windows. Note: Important for CGI users Read the faq on cgi.force_redirect for important details. This directive needs to be set to 0. If you want to use $_SERVER['PHP_SELF'] you have to enable the cgi.fix_pathinfo directive. Warning A server deployed in CGI mode is open to several possible vulnerabilities. Please read our CGI security section to learn how to defend yourself from such attacks. * Make sure the web server is running, and point your browser to xitamis admin console (usually http://127.0.0.1/admin), and click on Configuration. * Navigate to the Filters, and put the extension which PHP should parse (i.e. .php) into the field File extensions (.xxx). * In Filter command or script put the path and name of your PHP CGI executable i.e. C:\php\php.exe for PHP 4, or C:\php\php-cgi.exe for PHP 5. * Press the 'Save' icon. * Restart the server to reflect changes. ---------------------------------------------------------------------- ---------------------------------------------------------------------- Building from source This chapter teaches how to compile PHP from sources on windows, using Microsoft's tools. To compile PHP with cygwin, please refer to Installation on Unix systems. See the Wiki documentation at: >> http://wiki.php.net/internals/windows/stepbystepbuild ---------------------------------------------------------------------- ---------------------------------------------------------------------- Installation of extensions on Windows After installing PHP and a web server on Windows, you will probably want to install some extensions for added functionality. You can choose which extensions you would like to load when PHP starts by modifying your php.ini. You can also load a module dynamically in your script using dl(). The DLLs for PHP extensions are prefixed with php_. Many extensions are built into the Windows version of PHP. This means additional DLL files, and the extension directive, are not used to load these extensions. The Windows PHP Extensions table lists extensions that require, or used to require, additional PHP DLL files. Here's a list of built in extensions: In PHP 4 (updated PHP 4.3.11): BCMath, Caledar, COM, Ctype, FTP, MySQL, ODBC, Overload, PCRE, Session, Tokenizer, WDDX, XML and Zlib In PHP 5 (updated PHP 5.0.4), the following changes exist. Built in: DOM, LibXML, Iconv, SimpleXML, SPL and SQLite. And the following are no longer built in: MySQL and Overload. The default location PHP searches for extensions is C:\php4\extensions in PHP 4 and C:\php5 in PHP 5. To change this setting to reflect your setup of PHP edit your php.ini file: * You will need to change the extension_dir setting to point to the directory where your extensions lives, or where you have placed your php_*.dll files. For example: extension_dir = C:\php\extensions * Enable the extension(s) in php.ini you want to use by uncommenting the extension=php_*.dll lines in php.ini. This is done by deleting the leading ; from the extension you want to load. Example #1 Enable Bzip2 extension for PHP-Windows // change the following line from ... ;extension=php_bz2.dll // ... to extension=php_bz2.dll * Some of the extensions need extra DLLs to work. Couple of them can be found in the distribution package, in the C:\php\dlls\ folder in PHP 4 or in the main folder in PHP 5, but some, for example Oracle (php_oci8.dll) require DLLs which are not bundled with the distribution package. If you are installing PHP 4, copy the bundled DLLs from C:\php\dlls folder to the main C:\php folder. Don't forget to include C:\php in the system PATH (this process is explained in a separate FAQ entry). * Some of these DLLs are not bundled with the PHP distribution. See each extensions documentation page for details. Also, read the manual section titled Installation of PECL extensions for details on PECL. An increasingly large number of PHP extensions are found in PECL, and these extensions require a separate download. Note: If you are running a server module version of PHP remember to restart your web server to reflect your changes to php.ini. The following table describes some of the extensions available and required additional dlls. PHP Extensions Extension Description Notes php_bz2.dll bzip2 compression None functions php_calendar.dll Calendar conversion Built in since PHP 4.0.3 functions php_crack.dll Crack functions None php_ctype.dll ctype family functions Built in since PHP 4.3.0 php_curl.dll CURL, Client URL Requires: libeay32.dll, library functions ssleay32.dll (bundled) DBA: DataBase php_dba.dll (dbm-style) None Abstraction layer functions php_dbase.dll dBase functions None php_dbx.dll dbx functions PHP <= 4.2.0 requires: php_domxml.dll DOM XML functions libxml2.dll (bundled) PHP >= 4.3.0 requires: iconv.dll (bundled) php_dotnet.dll .NET functions PHP <= 4.1.1 php_mbstring.dll. And, php_exif.dll EXIF functions php_exif.dll must be loaded after php_mbstring.dll in php.ini. php_fbsql.dll FrontBase functions PHP <= 4.2.0 php_fdf.dll FDF: Forms Data Format Requires: fdftk.dll (bundled) functions. php_filepro.dll filePro functions Read-only access php_ftp.dll FTP functions Built-in since PHP 4.0.3 Removed in PHP 4.3.2. Also note php_gd.dll GD library image that truecolor functions are not functions available in GD1, instead, use php_gd2.dll. php_gd2.dll GD library image GD2 functions PHP <= 4.2.0 requires php_gettext.dll Gettext functions gnu_gettext.dll (bundled), PHP >= 4.2.3 requires libintl-1.dll, iconv.dll (bundled). php_hyperwave.dll HyperWave functions None php_iconv.dll ICONV characterset Requires: iconv-1.3.dll conversion (bundled), PHP >=4.2.1 iconv.dll php_ifx.dll Informix functions Requires: Informix libraries php_iisfunc.dll IIS management None functions php_imap.dll IMAP POP3 and NNTP None functions php_ingres.dll Ingres functions Requires: Ingres libraries php_interbase.dll InterBase functions Requires: gds32.dll (bundled) php_java.dll Java functions PHP <= 4.0.6 requires: jvm.dll (bundled) PHP <= 4.2.0 requires php_ldap.dll LDAP functions libsasl.dll (bundled), PHP >= 4.3.0 requires libeay32.dll, ssleay32.dll (bundled) php_mbstring.dll Multi-Byte String None functions php_mcrypt.dll Mcrypt Encryption Requires: libmcrypt.dll functions php_mhash.dll Mhash functions PHP >= 4.3.0 requires: libmhash.dll (bundled) php_mime_magic.dll Mimetype functions Requires: magic.mime (bundled) php_ming.dll Ming functions for None Flash php_msql.dll mSQL functions Requires: msql.dll (bundled) php_mssql.dll MSSQL functions Requires: ntwdblib.dll (bundled) php_mysql.dll MySQL functions PHP >= 5.0.0, requires libmysql.dll (bundled) PHP >= 5.0.0, requires php_mysqli.dll MySQLi functions libmysql.dll (libmysqli.dll in PHP <= 5.0.2) (bundled) php_oci8.dll Oracle 8 functions Requires: Oracle 8.1+ client libraries php_openssl.dll OpenSSL functions Requires: libeay32.dll (bundled) php_overload.dll Object overloading Built in since PHP 4.3.0 functions php_pdf.dll PDF functions None php_pgsql.dll PostgreSQL functions None php_printer.dll Printer functions None php_shmop.dll Shared Memory None functions php_snmp.dll SNMP get and walk NT only! functions php_soap.dll SOAP functions PHP >= 5.0.0 php_sockets.dll Socket functions None php_sybase_ct.dll Sybase functions Requires: Sybase client libraries php_tidy.dll Tidy functions PHP >= 5.0.0 php_tokenizer.dll Tokenizer functions Built in since PHP 4.3.0 php_w32api.dll W32api functions None php_xmlrpc.dll XML-RPC functions PHP >= 4.2.1 requires: iconv.dll (bundled) PHP <= 4.2.0 requires sablot.dll, expat.dll (bundled). php_xslt.dll XSLT functions PHP >= 4.2.1 requires sablot.dll, expat.dll, iconv.dll (bundled). php_yaz.dll YAZ functions Requires: yaz.dll (bundled) php_zip.dll Zip File functions Read only access php_zlib.dll ZLib compression Built in since PHP 4.3.0 functions ---------------------------------------------------------------------- ---------------------------------------------------------------------- Command Line PHP on Microsoft Windows This section contains notes and hints specific to getting PHP running from the command line for Windows. Note: You should read the manual installation steps first! Getting PHP to run from the command line can be performed without making any changes to Windows. C:\PHP5\php.exe -f "C:\PHP Scripts\script.php" -- -arg1 -arg2 -arg3 But there are some easy steps that can be followed to make this simpler. Some of these steps should already have been taken, but are repeated here to be able to provide a complete step-by-step sequence. * Add the location of the PHP executable (php.exe, php-win.exe or php-cli.exe depending upon your PHP version and display preferences) to the PATH environment variable. Read more about how to add your PHP directory to PATH in the corresponding FAQ entry. * Add the .PHP extension to the PATHEXT environment variable. This can be done at the same time as amending the PATH environment variable. Follow the same steps as described in the FAQ but amend the PATHEXT environment variable rather than the PATH environment variable. Note: The position in which you place the .PHP will determine which script or program is executed when there are matching filenames. For example, placing .PHP before .BAT will cause your script to run, rather than the batch file, if there is a batch file with the same name. * Associate the .PHP extension with a file type. This is done by running the following command: assoc .php=phpfile * Associate the phpfile file type with the appropriate PHP executable. This is done by running the following command: ftype phpfile="C:\PHP5\php.exe" -f "%1" -- %~2 Following these steps will allow PHP scripts to be run from any directory without the need to type the PHP executable or the .PHP extension and all parameters will be supplied to the script for processing. The example below details some of the registry changes that can be made manually. Example #1 Registry changes Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SOFTWARE\Classes\.php] @="phpfile" "Content Type"="application/php" [HKEY_LOCAL_MACHINE\SOFTWARE\Classes\phpfile] @="PHP Script" "EditFlags"=dword:00000000 "BrowserFlags"=dword:00000008 "AlwaysShowExt"="" [HKEY_LOCAL_MACHINE\SOFTWARE\Classes\phpfile\DefaultIcon] @="C:\\PHP5\\php-win.exe0" [HKEY_LOCAL_MACHINE\SOFTWARE\Classes\phpfile\shell] @="Open" [HKEY_LOCAL_MACHINE\SOFTWARE\Classes\phpfile\shell\Open] @="&Open" [HKEY_LOCAL_MACHINE\SOFTWARE\Classes\phpfile\shell\Open\command] @="\"C:\\PHP5\\php.exe\" -f \"%1\" -- %~2" With these changes the same command can be written as: "C:\PHP Scripts\script" -arg1 -arg2 -arg3 or, if your "C:\PHP Scripts" path is in the PATH environment variable: script -arg1 -arg2 -arg3 Note: There is a small problem if you intend to use this technique and use your PHP scripts as a command line filter, like the example below: dir | "C:\PHP Scripts\script" -arg1 -arg2 -arg3 or dir | script -arg1 -arg2 -arg3 You may find that the script simply hangs and nothing is output. To get this operational, you need to make another registry change. Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\policies\Explorer] "InheritConsoleHandles"=dword:00000001 Further information regarding this issue can be found in this >> Microsoft Knowledgebase Article : 321788. ---------------------------------------------------------------------- ---------------------------------------------------------------------- ---------------------------------------------------------------------- Installation on Cloud Computing platforms Table of Contents * Microsoft Azure * Amazon EC2 PHP installs on the cloud. To the PHP cloud! ---------------------------------------------------------------------- Microsoft Azure PHP installs on the >> Azure cloud platform. See also the >> Azure SDK for PHP. ---------------------------------------------------------------------- ---------------------------------------------------------------------- Amazon EC2 PHP installs on the >> EC2 cloud platform. See also the >> AWS SDK for PHP. ---------------------------------------------------------------------- ---------------------------------------------------------------------- ---------------------------------------------------------------------- FastCGI Process Manager (FPM) Table of Contents * Installation * Configuration FPM (FastCGI Process Manager) is an alternative PHP FastCGI implementation with some additional features (mostly) useful for heavy-loaded sites. These features include: * advanced process management with graceful stop/start; * ability to start workers with different uid/gid/chroot/environment, listening on different ports and using different php.ini (replaces safe_mode); * stdout and stderr logging; * emergency restart in case of accidental opcode cache destruction; * accelerated upload support; * "slowlog" - logging scripts (not just their names, but their PHP backtraces too, using ptrace and similar things to read remote process' execute_data) that are executed unusually slow; * fastcgi_finish_request() - special function to finish request and flush all data while continuing to do something time-consuming (video converting, stats processing etc.); * dynamic/static child spawning; * basic SAPI status info (similar to Apache mod_status); * php.ini-based config file. ---------------------------------------------------------------------- Installation Prerequisites FPM uses libevent to manage connections and signals. Minimum required version is libevent-1.4.11. Compiling from sources In order to enable FPM in your PHP build you need to add --enable-fpm to your configure line. There are several other FPM-specific configure options (all of them optional): * --with-fpm-user - set FPM user (default - nobody). * --with-fpm-group - set FPM group (default - nobody). ---------------------------------------------------------------------- ---------------------------------------------------------------------- Configuration FPM uses php.ini syntax for its configuration file - php-fpm.conf. List of global php-fpm.conf directives pid string Path to PID file. Default value: none. error_log string Path to error log file. Default value: #INSTALL_PREFIX#/log/php-fpm.log. log_level string Error log level. Possible values: alert, error, warning, notice, debug. Default value: notice. emergency_restart_threshold int If this number of child processes exit with SIGSEGV or SIGBUS within the time interval set by emergency_restart_interval then FPM will restart. A value of 0 means 'Off'. Default value: 0 (Off). emergency_restart_interval mixed Interval of time used by emergency_restart_interval to determine when a graceful restart will be initiated. This can be useful to work around accidental corruptions in an accelerator's shared memory. Available Units: s(econds), m(inutes), h(ours), or d(ays). Default Unit: seconds. Default value: 0 (Off). process_control_timeout mixed Time limit for child processes to wait for a reaction on signals from master. Available units: s(econds), m(inutes), h(ours), or d(ays) Default Unit: seconds. Default value: 0. daemonize boolean Send FPM to background. Set to 'no' to keep FPM in foreground for debugging. Default value: yes. List of pool directives With FPM you can run several pools of processes with different setting. These are settings that can be tweaked per pool. listen string The address on which to accept FastCGI requests. Valid syntaxes are: 'ip.add.re.ss:port', 'port', '/path/to/unix/socket'. This option is mandatory for each pool. listen.backlog int Set listen(2) backlog. A value of '-1' means unlimited. Default value: -1. listen.allowed_clients string List of ipv4 addresses of FastCGI clients which are allowed to connect. Equivalent to the FCGI_WEB_SERVER_ADDRS environment variable in the original PHP FastCGI (5.2.2+). Makes sense only with a tcp listening socket. Each address must be separated by a comma. If this value is left blank, connections will be accepted from any ip address. Default value: any. listen.owner string Set permissions for unix socket, if one is used. In Linux, read/write permissions must be set in order to allow connections from a web server. Many BSD-derived systems allow connections regardless of permissions. Default values: user and group are set as the running user, mode is set to 0666. listen.group string See listen.owner. listen.mode string See listen.owner. user string Unix user of FPM processes. This option is mandatory. group string Unix group of FPM processes. If not set, the default user's group is used. pm string Choose how the process manager will control the number of child processes. Possible values: static, dynamic. This option is mandatory. static - the number of child processes is fixed (pm.max_children). dynamic - the number of child processes is set dynamically based on the following directives: pm.max_children, pm.start_servers, pm.min_spare_servers, pm.max_spare_servers. pm.max_children int The number of child processes to be created when pm is set to static and the maximum number of child processes to be created when pm is set to dynamic. This option is mandatory. This option sets the limit on the number of simultaneous requests that will be served. Equivalent to the ApacheMaxClients directive with mpm_prefork and to the PHP_FCGI_CHILDREN environment variable in the original PHP FastCGI. pm.start_servers in The number of child processes created on startup. Used only when pm is set to dynamic. Default Value: min_spare_servers + (max_spare_servers - min_spare_servers) / 2. pm.min_spare_servers int The desired minimum number of idle server processes. Used only when pm is set to dynamic. Also mandatory in this case. pm.max_spare_servers int The desired maximum number of idle server processes. Used only when pm is set to dynamic. Also mandatory in this case. pm.max_requests int The number of requests each child process should execute before respawning. This can be useful to work around memory leaks in 3rd party libraries. For endless request processing specify '0'. Equivalent to PHP_FCGI_MAX_REQUESTS. Default value: 0. pm.status_path string The URI to view the FPM status page. If this value is not set, no URI will be recognized as a status page. Default value: none. ping.path string The ping URI to call the monitoring page of FPM. If this value is not set, no URI will be recognized as a ping page. This could be used to test from outside that FPM is alive and responding. Please note that the value must start with a leading slash (/). ping.response string This directive may be used to customize the response to a ping request. The response is formatted as text/plain with a 200 response code. Default value: pong. request_terminate_timeout mixed The timeout for serving a single request after which the worker process will be killed. This option should be used when the 'max_execution_time' ini option does not stop script execution for some reason. A value of '0' means 'Off'. Available units: s(econds)(default), m(inutes), h(ours), or d(ays). Default value: 0. request_slowlog_timeout mixed The timeout for serving a single request after which a PHP backtrace will be dumped to the 'slowlog' file. A value of '0' means 'Off'. Available units: s(econds)(default), m(inutes), h(ours), or d(ays). Default value: 0. slowlog string The log file for slow requests. Default value: #INSTALL_PREFIX#/log/php-fpm.log.slow. rlimit_files int Set open file descriptor rlimit. Default value: system defined value. rlimit_core int Set max core size rlimit. Possible Values: 'unlimited' or an integer greater or equal to 0. Default value: system defined value. chroot string Chroot to this directory at the start. This value must be defined as an absolute path. When this value is not set, chroot is not used. chdir string Chdir to this directory at the start. This value must be an absolute path. Default value: current directory or / when chroot. catch_workers_output boolean Redirect worker stdout and stderr into main error log. If not set, stdout and stderr will be redirected to /dev/null according to FastCGI specs. Default value: no. It's possible to pass additional environment variables and update PHP settings of a ceratian pool. To do this, you need to add the following options to php-fpm.conf Example #1 Passing environment variables and PHP settings to a pool env[HOSTNAME] = $HOSTNAME env[PATH] = /usr/local/bin:/usr/bin:/bin env[TMP] = /tmp env[TMPDIR] = /tmp env[TEMP] = /tmp php_admin_value[sendmail_path] = /usr/sbin/sendmail -t -i -f www@my.domain.com php_flag[display_errors] = off php_admin_value[error_log] = /var/log/fpm-php.www.log php_admin_flag[log_errors] = on php_admin_value[memory_limit] = 32M PHP settings passed with php_value or php_flag will overwrite their previous value. Please note that defining disable_functions or disable_classes will not overwrite previously defined php.ini values, but will append the new value instead. Settings defined with php_admin_value and php_admin_flag cannot be overriden with ini_set(). ---------------------------------------------------------------------- ---------------------------------------------------------------------- ---------------------------------------------------------------------- Installation of PECL extensions Table of Contents * Introduction to PECL Installations * Downloading PECL extensions * Installing a PHP extension on Windows * Compiling shared PECL extensions with the pecl command * Compiling shared PECL extensions with phpize * php-config * Compiling PECL extensions statically into PHP ---------------------------------------------------------------------- Introduction to PECL Installations >> PECL is a repository of PHP extensions that are made available to you via the >> PEAR packaging system. This section of the manual is intended to demonstrate how to obtain and install PECL extensions. These instructions assume /your/phpsrcdir/ is the path to the PHP source distribution, and that extname is the name of the PECL extension. Adjust accordingly. These instructions also assume a familiarity with the >> pear command. The information in the PEAR manual for the pear command also applies to the pecl command. To be useful, a shared extension must be built, installed, and loaded. The methods described below provide you with various instructions on how to build and install the extensions, but they do not automatically load them. Extensions can be loaded by adding an extension directive. To this php.ini file, or through the use of the dl() function. When building PHP modules, it's important to have known-good versions of the required tools (autoconf, automake, libtool, etc.) See the >> Anonymous SVN Instructions for details on the required tools, and required versions. ---------------------------------------------------------------------- ---------------------------------------------------------------------- Downloading PECL extensions There are several options for downloading PECL extensions, such as: * The pecl install extname command downloads the extensions code automatically, so in this case there is no need for a separate download. * >> http://pecl.php.net/ The PECL web site contains information about the different extensions that are offered by the PHP Development Team. The information available here includes: ChangeLog, release notes, requirements and other similar details. * pecl download extname PECL extensions that have releases listed on the PECL web site are available for download and installation using the >> pecl command. Specific revisions may also be specified. * SVN Most PECL extensions also reside in SVN. A web-based view may be seen at >> http://svn.php.net/viewvc/pecl/. To download straight from SVN, the following sequence of commands may be used: $ svn checkout http://svn.php.net/repository/pecl/extname/trunk extname * Windows downloads At this time the PHP project does not compile Windows binaries for PECL extensions. However, to compile PHP under Windows see the chapter titled building PHP for Windows. ---------------------------------------------------------------------- ---------------------------------------------------------------------- Installing a PHP extension on Windows On Windows, you have two ways to load a PHP extension: either compile it into PHP, or load the DLL. Loading a pre-compiled extension is the easiest and preferred way. To load an extension, you need to have it available as a ".dll" file on your system. All the extensions are automatically and periodically compiled by the PHP Group (see next section for the download). To compile an extension into PHP, please refer to building from source documentation. To compile a standalone extension (aka a DLL file), please refer to building from source documentation. If the DLL file is available neither with your PHP distribution nor in PECL, you may have to compile it before you can start using the extension. Where to find an extension? PHP extensions are usually called "php_*.dll" (where the star represents the name of the extension) and they are located under the "PHP\ext" ("PHP\extensions" in PHP4) folder. PHP ships with the extensions most useful to the majority of developers. They are called "core" extensions. However, if you need functionality not provided by any core extension, you may still be able to find one in PECL. The PHP Extension Community Library (PECL) is a repository for PHP Extensions, providing a directory of all known extensions and hosting facilities for downloading and development of PHP extensions. If you have developed an extension for your own uses, you might want to think about hosting it on PECL so that others with the same needs can benefit from your time. A nice side effect is that you give them a good chance to give you feedback, (hopefully) thanks, bug reports and even fixes/patches. Before you submit your extension for hosting on PECL, please read http://pecl.php.net/package-new.php. Which extension to download? Many times, you will find several versions of each DLL: * Different version numbers (at least the first two numbers should match) * Different thread safety settings * Different processor architecture (x86, x64, ...) * Different debugging settings * etc. You should keep in mind that your extension settings should match all the settings of the PHP executable you are using. The following PHP script will tell you all about your PHP settings: Example #1 phpinfo() call Or from the command line, run: drive:\\path\to\php\executable\php.exe -i Loading an extension The most common way to load a PHP extension is to include it in your php.ini configuration file. Please note that many extensions are already present in your php.ini and that you only need to remove the semicolon to activate them. ;extension=php_extname.dll extension=php_extname.dll However, some web servers are confusing because they do not use the php.ini located alongside your PHP executable. To find out where your actual php.ini resides, look for its path in phpinfo(): Configuration File (php.ini) Path C:\WINDOWS Loaded Configuration File C:\Program Files\PHP\5.2\php.ini After activating an extension, save php.ini, restart the web server and check phpinfo() again. The new extension should now have its own section. Resolving problems If the extension does not appear in phpinfo(), you should check your logs to learn where the problem comes from. If you are using PHP from the command line (CLI), the extension loading error can be read directly on screen. If you are using PHP with a web server, the location and format of the logs vary depending on your software. Please read your web server documentation to locate the logs, as it does not have anything to do with PHP itself. Common problems are the location of the DLL, the value of the " extension_dir" setting inside php.ini and compile-time setting mismatches. If the problem lies in a compile-time setting mismatch, you probably didn't download the right DLL. Try downloading again the extension with the right settings. Again, phpinfo() can be of great help. ---------------------------------------------------------------------- ---------------------------------------------------------------------- Compiling shared PECL extensions with the pecl command PECL makes it easy to create shared PHP extensions. Using the >> pecl command, do the following: $ pecl install extname This will download the source for extname, compile, and install extname.so into your extension_dir. extname.so may then be loaded via php.ini By default, the pecl command will not install packages that are marked with the alpha or beta state. If no stable packages are available, you may install a beta package using the following command: $ pecl install extname-beta You may also install a specific version using this variant: $ pecl install extname-0.1 Note: After enabling the extension in php.ini, restarting the web service is required for the changes to be picked up. ---------------------------------------------------------------------- ---------------------------------------------------------------------- Compiling shared PECL extensions with phpize Sometimes, using the pecl installer is not an option. This could be because you're behind a firewall, or it could be because the extension you want to install is not available as a PECL compatible package, such as unreleased extensions from SVN. If you need to build such an extension, you can use the lower-level build tools to perform the build manually. The phpize command is used to prepare the build environment for a PHP extension. In the following sample, the sources for an extension are in a directory named extname: $ cd extname $ phpize $ ./configure $ make # make install A successful install will have created extname.so and put it into the PHP extensions directory. You'll need to and adjust php.ini and add an extension=extname.so line before you can use the extension. If the system is missing the phpize command, and precompiled packages (like RPM's) are used, be sure to also install the appropriate devel version of the PHP package as they often include the phpize command along with the appropriate header files to build PHP and its extensions. Execute phpize --help to display additional usage information. ---------------------------------------------------------------------- ---------------------------------------------------------------------- php-config php-config is a simple shell script for obtaining information about the installed PHP configuration. When compiling extensions, if you have multiple PHP versions installed, you may specify for which installation you'd like to build by using the --with-php-config option during configuration, specifying the path of the respective php-config script. The list of command line options provided by the php-config script can be queried anytime by running php-config with the -h switch: Usage: /usr/local/bin/php-config [OPTION] Options: --prefix [...] --includes [...] --ldflags [...] --libs [...] --extension-dir [...] --include-dir [...] --php-binary [...] --php-sapis [...] --configure-options [...] --version [...] --vernum [...] Command line options Option Description --prefix Directory prefix where PHP is installed, e.g. /usr/local --includes List of -I options with all include files --ldflags LD Flags which PHP was compiled with --libs Extra libraries which PHP was compiled with --extension-dir Directory where extensions are searched by default --include-dir Directory prefix where header files are installed by default --php-binary Full path to php CLI or CGI binary --php-sapis Show all SAPI modules available --configure-options Configure options to recreate configuration of current PHP installation --version PHP version --vernum PHP version as integer ---------------------------------------------------------------------- ---------------------------------------------------------------------- Compiling PECL extensions statically into PHP You might find that you need to build a PECL extension statically into your PHP binary. To do this, you'll need to place the extension source under the php-src/ext/ directory and tell the PHP build system to regenerate its configure script. $ cd /your/phpsrcdir/ext $ pecl download extname $ gzip -d < extname.tgz | tar -xvf - $ mv extname-x.x.x extname This will result in the following directory: /your/phpsrcdir/ext/extname From here, force PHP to rebuild the configure script, and then build PHP as normal: $ cd /your/phpsrcdir $ rm configure $ ./buildconf --force $ ./configure --help $ ./configure --with-extname --enable-someotherext --with-foobar $ make $ make install Note: To run the 'buildconf' script you need autoconf 2.13 and automake 1.4+ (newer versions of autoconf may work, but are not supported). Whether --enable-extname or --with-extname is used depends on the extension. Typically an extension that does not require external libraries uses --enable. To be sure, run the following after buildconf: $ ./configure --help | grep extname ---------------------------------------------------------------------- ---------------------------------------------------------------------- ---------------------------------------------------------------------- Problems? Table of Contents * Read the FAQ * Other problems * Bug reports ---------------------------------------------------------------------- Read the FAQ Some problems are more common than others. The most common ones are listed in the PHP FAQ, part of this manual. ---------------------------------------------------------------------- ---------------------------------------------------------------------- Other problems If you are still stuck, someone on the PHP installation mailing list may be able to help you. You should check out the archive first, in case someone already answered someone else who had the same problem as you. The archives are available from the support page on >> http://www.php.net/support.php. To subscribe to the PHP installation mailing list, send an empty mail to >> php-install-subscribe@lists.php.net. The mailing list address is >> php-install@lists.php.net. If you want to get help on the mailing list, please try to be precise and give the necessary details about your environment (which operating system, what PHP version, what web server, if you are running PHP as CGI or a server module, safe mode, etc.), and preferably enough code to make others able to reproduce and test your problem. ---------------------------------------------------------------------- ---------------------------------------------------------------------- Bug reports If you think you have found a bug in PHP, please report it. The PHP developers probably don't know about it, and unless you report it, chances are it won't be fixed. You can report bugs using the bug-tracking system at >> http://bugs.php.net/. Please do not send bug reports in mailing list or personal letters. The bug system is also suitable to submit feature requests. Read the >> How to report a bug document before submitting any bug reports! ---------------------------------------------------------------------- ---------------------------------------------------------------------- ---------------------------------------------------------------------- Runtime Configuration Table of Contents * The configuration file * .user.ini files * Where a configuration setting may be set * How to change configuration settings ---------------------------------------------------------------------- The configuration file The configuration file (php.ini) is read when PHP starts up. For the server module versions of PHP, this happens only once when the web server is started. For the CGI and CLI versions, it happens on every invocation. php.ini is searched for in these locations (in order): * SAPI module specific location (PHPIniDir directive in Apache 2, -c command line option in CGI and CLI, php_ini parameter in NSAPI, PHP_INI_PATH environment variable in THTTPD) * The PHPRC environment variable. Before PHP 5.2.0, this was checked after the registry key mentioned below. * As of PHP 5.2.0, the location of the php.ini file can be set for different versions of PHP. The following registry keys are examined in order: [HKEY_LOCAL_MACHINE\SOFTWARE\PHP\x.y.z], [HKEY_LOCAL_MACHINE\SOFTWARE\PHP\x.y] and [HKEY_LOCAL_MACHINE\SOFTWARE\PHP\x], where x, y and z mean the PHP major, minor and release versions. If there is a value for IniFilePath in any of these keys, the first one found will be used as the location of the php.ini (Windows only). * [HKEY_LOCAL_MACHINE\SOFTWARE\PHP], value of IniFilePath (Windows only). * Current working directory (except CLI). * The web server's directory (for SAPI modules), or directory of PHP (otherwise in Windows). * Windows directory (C:\windows or C:\winnt) (for Windows), or --with-config-file-path compile time option. If php-SAPI.ini exists (where SAPI is the SAPI in use, so, for example, php-cli.ini or php-apache.ini), it is used instead of php.ini. The SAPI name can be determined with php_sapi_name(). Note: The Apache web server changes the directory to root at startup, causing PHP to attempt to read php.ini from the root filesystem if it exists. The php.ini directives handled by extensions are documented on the respective pages of the extensions themselves. A list of the core directives is available in the appendix. Not all PHP directives are necessarily documented in this manual: for a complete list of directives available in your PHP version, please read your well commented php.ini file. Alternatively, you may find >> the latest php.ini from SVN helpful too. Example #1 php.ini example ; any text on a line after an unquoted semicolon (;) is ignored [php] ; section markers (text within square brackets) are also ignored ; Boolean values can be set to either: ; true, on, yes ; or false, off, no, none register_globals = off track_errors = yes ; you can enclose strings in double-quotes include_path = ".:/usr/local/lib/php" ; backslashes are treated the same as any other character include_path = ".;c:\php\lib" Since PHP 5.1.0, it is possible to refer to existing .ini variables from within .ini files. Example: open_basedir = ${open_basedir} ":/new/dir". ---------------------------------------------------------------------- ---------------------------------------------------------------------- .user.ini files Since PHP 5.3.0, PHP includes support for .htaccess-style INI files on a per-directory basis. These files are processed only by the CGI/FastCGI SAPI. This functionality obsoletes the PECL htscanner extension. If you are using Apache, use .htaccess files for the same effect. In addition to the main php.ini file, PHP scans for INI files in each directory, starting with the directory of the requested PHP file, and working its way up to the current document root (as set in $_SERVER['DOCUMENT_ROOT']). In case the PHP file is outside the document root, only its directory is scanned. Only INI settings with the modes PHP_INI_PERDIR and PHP_INI_USER will be recognized in .user.ini-style INI files. Two new INI directives, user_ini.filename and user_ini.cache_ttl control the use of user INI files. user_ini.filename sets the name of the file PHP looks for in each directory; if set to an empty string, PHP doesn't scan at all. The default is .user.ini. user_ini.cache_ttl controls how often user INI files are re-read. The default is 300 seconds (5 minutes). ---------------------------------------------------------------------- ---------------------------------------------------------------------- Where a configuration setting may be set These modes determine when and where a PHP directive may or may not be set, and each directive within the manual refers to one of these modes. For example, some settings may be set within a PHP script using ini_set(), whereas others may require php.ini or httpd.conf. For example, the output_buffering setting is PHP_INI_PERDIR therefore it may not be set using ini_set(). However, the display_errors directive is PHP_INI_ALL therefore it may be set anywhere, including with ini_set(). Definition of PHP_INI_* modes Mode Value Meaning PHP_INI_USER 1 Entry can be set in user scripts (like with ini_set()) or in the Windows registry PHP_INI_PERDIR 6 Entry can be set in php.ini, .htaccess or httpd.conf PHP_INI_SYSTEM 4 Entry can be set in php.ini or httpd.conf PHP_INI_ALL 7 Entry can be set anywhere ---------------------------------------------------------------------- ---------------------------------------------------------------------- How to change configuration settings Running PHP as an Apache module When using PHP as an Apache module, you can also change the configuration settings using directives in Apache configuration files (e.g. httpd.conf) and .htaccess files. You will need "AllowOverride Options" or "AllowOverride All" privileges to do so. There are several Apache directives that allow you to change the PHP configuration from within the Apache configuration files. For a listing of which directives are PHP_INI_ALL, PHP_INI_PERDIR, or PHP_INI_SYSTEM, have a look at the List of php.ini directives appendix. php_value name value Sets the value of the specified directive. Can be used only with PHP_INI_ALL and PHP_INI_PERDIR type directives. To clear a previously set value use none as the value. Note: Don't use php_value to set boolean values. php_flag (see below) should be used instead. php_flag name on|off Used to set a boolean configuration directive. Can be used only with PHP_INI_ALL and PHP_INI_PERDIR type directives. php_admin_value name value Sets the value of the specified directive. This can not be used in .htaccess files. Any directive type set with php_admin_value can not be overridden by .htaccess or ini_set(). To clear a previously set value use none as the value. php_admin_flag name on|off Used to set a boolean configuration directive. This can not be used in .htaccess files. Any directive type set with php_admin_flag can not be overridden by .htaccess or ini_set(). Example #1 Apache configuration example php_value include_path ".:/usr/local/lib/php" php_admin_flag engine on php_value include_path ".:/usr/local/lib/php" php_admin_flag engine on Caution PHP constants do not exist outside of PHP. For example, in httpd.conf you can not use PHP constants such as E_ALL or E_NOTICE to set the error_reporting directive as they will have no meaning and will evaluate to 0. Use the associated bitmask values instead. These constants can be used in php.ini Changing PHP configuration via the Windows registry When running PHP on Windows, the configuration values can be modified on a per-directory basis using the Windows registry. The configuration values are stored in the registry key HKLM\SOFTWARE\PHP\Per Directory Values, in the sub-keys corresponding to the path names. For example, configuration values for the directory c:\inetpub\wwwroot would be stored in the key HKLM\SOFTWARE\PHP\Per Directory Values\c\inetpub\wwwroot. The settings for the directory would be active for any script running from this directory or any subdirectory of it. The values under the key should have the name of the PHP configuration directive and the string value. PHP constants in the values are not parsed. However, only configuration values changeable in PHP_INI_USER can be set this way, PHP_INI_PERDIR values can not. Other interfaces to PHP Regardless of how you run PHP, you can change certain values at runtime of your scripts through ini_set(). See the documentation on the ini_set() page for more information. If you are interested in a complete list of configuration settings on your system with their current values, you can execute the phpinfo() function, and review the resulting page. You can also access the values of individual configuration directives at runtime using ini_get() or get_cfg_var(). ---------------------------------------------------------------------- ---------------------------------------------------------------------- * General Installation Considerations * Installation on Unix systems * Apache 1.3.x on Unix systems * Apache 2.x on Unix systems * Lighttpd 1.4 on Unix systems * Sun, iPlanet and Netscape servers on Sun Solaris * CGI and command line setups * HP-UX specific installation notes * OpenBSD installation notes * Solaris specific installation tips * Debian GNU/Linux installation notes * Installation on Mac OS X * Using Packages * Using the bundled PHP * Compiling PHP on Mac OS X * Installation on Windows systems * Windows Installer (PHP 5.1.0 and earlier) * Windows Installer (PHP 5.2 and later) * Manual Installation Steps * ActiveScript * Microsoft IIS * Microsoft IIS 5.1 and IIS 6.0 * Microsoft IIS 7.0 and later * Apache 1.3.x on Microsoft Windows * Apache 2.x on Microsoft Windows * Sun, iPlanet and Netscape servers on Microsoft Windows * OmniHTTPd Server * Sambar Server on Microsoft Windows * Xitami on Microsoft Windows * Building from source * Installation of extensions on Windows * Command Line PHP on Microsoft Windows * Installation on Cloud Computing platforms * Microsoft Azure * Amazon EC2 * FastCGI Process Manager (FPM) * Installation * Configuration * Installation of PECL extensions * Introduction to PECL Installations * Downloading PECL extensions * Installing a PHP extension on Windows * Compiling shared PECL extensions with the pecl command * Compiling shared PECL extensions with phpize * php-config * Compiling PECL extensions statically into PHP * Problems? * Read the FAQ * Other problems * Bug reports * Runtime Configuration * The configuration file * .user.ini files * Where a configuration setting may be set * How to change configuration settings ---------------------------------------------------------------------- ---------------------------------------------------------------------- Language Reference ---------------------------------------------------------------------- Basic syntax Table of Contents * Escaping from HTML * Instruction separation * Comments ---------------------------------------------------------------------- Escaping from HTML When PHP parses a file, it looks for opening and closing tags, which tell PHP to start and stop interpreting the code between them. Parsing in this manner allows PHP to be embedded in all sorts of different documents, as everything outside of a pair of opening and closing tags is ignored by the PHP parser. Most of the time you will see PHP embedded in HTML documents, as in this example.

This is going to be ignored.

This will also be ignored.

You can also use more advanced structures: Example #1 Advanced escaping This is true. This is false. This works as expected, because when PHP hits the ?> closing tags, it simply starts outputting whatever it finds (except for an immediately following newline - see instruction separation ) until it hits another opening tag. The example given here is contrived, of course, but for outputting large blocks of text, dropping out of PHP parsing mode is generally more efficient than sending all of the text through echo() or print(). There are four different pairs of opening and closing tags which can be used in PHP. Two of those, and , are always available. The other two are short tags and ASP style tags, and can be turned on and off from the php.ini configuration file. As such, while some people find short tags and ASP style tags convenient, they are less portable, and generally not recommended. Note: Also note that if you are embedding PHP within XML or XHTML you will need to use the tags to remain compliant with standards. Example #2 PHP Opening and Closing Tags 1. 2. 3. This is a shortcut for "" 4. <% echo 'You may optionally use ASP-style tags'; %> <%= $variable; # This is a shortcut for "<% echo . . ." %> While the tags seen in examples one and two are both always available, example one is the most commonly used, and recommended, of the two. Short tags (example three) are only available when they are enabled via the short_open_tag php.ini configuration file directive, or if PHP was configured with the --enable-short-tags option. ASP style tags (example four) are only available when they are enabled via the asp_tags php.ini configuration file directive. Note: Using short tags should be avoided when developing applications or libraries that are meant for redistribution, or deployment on PHP servers which are not under your control, because short tags may not be supported on the target server. For portable, redistributable code, be sure not to use short tags. Note: In PHP 5.2 and earlier, the parser does not allow the The "one-line" comment styles only comment to the end of the line or the current block of PHP code, whichever comes first. This means that HTML code after // ... ?> or # ... ?> WILL be printed: ?> breaks out of PHP mode and returns to HTML mode, and // or # cannot influence that. If the asp_tags configuration directive is enabled, it behaves the same with // %> and # %>. However, the tag doesn't break out of PHP mode in a one-line comment.

This is an example

The header above will say 'This is an example'.

'C' style comments end at the first */ encountered. Make sure you don't nest 'C' style comments. It is easy to make this mistake if you are trying to comment out a large block of code. ---------------------------------------------------------------------- ---------------------------------------------------------------------- ---------------------------------------------------------------------- Types Table of Contents * Introduction * Booleans * Integers * Floating point numbers * Strings * Arrays * Objects * Resources * NULL * Pseudo-types and variables used in this documentation * Type Juggling ---------------------------------------------------------------------- Introduction PHP supports eight primitive types. Four scalar types: * boolean * integer * float (floating-point number, aka double) * string Two compound types: * array * object And finally two special types: * resource * NULL This manual also introduces some pseudo-types for readability reasons: * mixed * number * callback And the pseudo-variable $.... Some references to the type "double" may remain in the manual. Consider double the same as float; the two names exist only for historic reasons. The type of a variable is not usually set by the programmer; rather, it is decided at runtime by PHP depending on the context in which that variable is used. Note: To check the type and value of an expression, use the var_dump() function. To get a human-readable representation of a type for debugging, use the gettype() function. To check for a certain type, do not use gettype(), but rather the is_type functions. Some examples: To forcibly convert a variable to a certain type, either cast the variable or use the settype() function on it. Note that a variable may be evaluated with different values in certain situations, depending on what type it is at the time. For more information, see the section on Type Juggling. The type comparison tables may also be useful, as they show examples of various type-related comparisons. ---------------------------------------------------------------------- ---------------------------------------------------------------------- Booleans This is the simplest type. A boolean expresses a truth value. It can be either TRUE or FALSE. Note: The boolean type was introduced in PHP 4. Syntax To specify a boolean literal, use the keywords TRUE or FALSE. Both are case-insensitive. Typically, the result of an operator which returns a boolean value is passed on to a control structure. \n"; } // ...because this can be used with exactly the same meaning: if ($show_separators) { echo "
\n"; } ?> Converting to boolean To explicitly convert a value to boolean, use the (bool) or (boolean) casts. However, in most cases the cast is unnecessary, since a value will be automatically converted if an operator, function or control structure requires a boolean argument. See also Type Juggling. When converting to boolean, the following values are considered FALSE: * the boolean FALSE itself * the integer 0 (zero) * the float 0.0 (zero) * the empty string, and the string "0" * an array with zero elements * an object with zero member variables (PHP 4 only) * the special type NULL (including unset variables) * SimpleXML objects created from empty tags Every other value is considered TRUE (including any resource). Warning -1 is considered TRUE, like any other non-zero (whether negative or positive) number! ---------------------------------------------------------------------- ---------------------------------------------------------------------- Integers An integer is a number of the set * = {..., -2, -1, 0, 1, 2, ...}. See also: * Arbitrary length integer / GMP * Floating point numbers * Arbitrary precision / BCMath Syntax Integers can be specified in decimal (base 10), hexadecimal (base 16), or octal (base 8) notation, optionally preceded by a sign (- or +). To use octal notation, precede the number with a 0 (zero). To use hexadecimal notation precede the number with 0x. Example #1 Integer literals Formally, the structure for integer literals is: decimal : [1-9][0-9]* | 0 hexadecimal : 0[xX][0-9a-fA-F]+ octal : 0[0-7]+ integer : [+-]?decimal | [+-]?hexadecimal | [+-]?octal The size of an integer is platform-dependent, although a maximum value of about two billion is the usual value (that's 32 bits signed). 64-bit platforms usually have a maximum value of about 9E18. PHP does not support unsigned integers. Integer size can be determined using the constant PHP_INT_SIZE, and maximum value using the constant PHP_INT_MAX since PHP 4.4.0 and PHP 5.0.5. Warning If an invalid digit is given in an octal integer (i.e. 8 or 9), the rest of the number is ignored. Example #2 Octal weirdness Integer overflow If PHP encounters a number beyond the bounds of the integer type, it will be interpreted as a float instead. Also, an operation which results in a number beyond the bounds of the integer type will return a float instead. Example #3 Integer overflow on a 32-bit system Example #4 Integer overflow on a 64-bit system There is no integer division operator in PHP. 1/2 yields the float 0.5. The value can be casted to an integer to round it downwards, or the round() function provides finer control over rounding. Converting to integer To explicitly convert a value to integer, use either the (int) or (integer) casts. However, in most cases the cast is not needed, since a value will be automatically converted if an operator, function or control structure requires an integer argument. A value can also be converted to integer with the intval() function. See also: type-juggling. From booleans FALSE will yield 0 (zero), and TRUE will yield 1 (one). From floating point numbers When converting from float to integer, the number will be rounded towards zero. If the float is beyond the boundaries of integer (usually +/- 2.15e+9 = 2^31 on 32-bit platforms and +/- 9.22e+18 = 2^63 on 64-bit platforms), the result is undefined, since the float doesn't have enough precision to give an exact integer result. No warning, not even a notice will be issued when this happens! Warning Never cast an unknown fraction to integer, as this can sometimes lead to unexpected results. See also the warning about float precision. From strings See String conversion to numbers From other types Caution The behaviour of converting to integer is undefined for other types. Do not rely on any observed behaviour, as it can change without notice. ---------------------------------------------------------------------- ---------------------------------------------------------------------- Floating point numbers Floating point numbers (also known as "floats", "doubles", or "real numbers") can be specified using any of the following syntaxes: Formally: LNUM [0-9]+ DNUM ([0-9]*[\.]{LNUM}) | ({LNUM}[\.][0-9]*) EXPONENT_DNUM [+-]?(({LNUM} | {DNUM}) [eE][+-]? {LNUM}) The size of a float is platform-dependent, although a maximum of ~1.8e308 with a precision of roughly 14 decimal digits is a common value (the 64 bit IEEE format). Warning Floating point precision Floating point numbers have limited precision. Although it depends on the system, PHP typically uses the IEEE 754 double precision format, which will give a maximum relative error due to rounding in the order of 1.11e-16. Non elementary arithmetic operations may give larger errors, and, of course, error progragation must be considered when several operations are compounded. Additionally, rational numbers that are exactly representable as floating point numbers in base 10, like 0.1 or 0.7, do not have an exact representation as floating point numbers in base 2, which is used internally, no matter the size of the mantissa. Hence, they cannot be converted into their internal binary counterparts without a small loss of precision. This can lead to confusing results: for example, floor((0.1+0.7)*10) will usually return 7 instead of the expected 8, since the internal representation will be something like 7.9999999999999991118.... So never trust floating number results to the last digit, and never compare floating point numbers for equality. If higher precision is necessary, the arbitrary precision math functions and gmp functions are available. Converting to float For information on converting strings to float, see String conversion to numbers. For values of other types, the conversion is performed by converting the value to integer first and then to float. See Converting to integer for more information. As of PHP 5, a notice is thrown if an object is converted to float. ---------------------------------------------------------------------- ---------------------------------------------------------------------- Strings A string is series of characters, where a character is the same as a byte. This means that PHP only supports a 256-character set, and hence does not offer native Unicode support. See utf8_encode() and utf8_decode() for some basic Unicode functionality. Note: It is no problem for a string to become very large. PHP imposes no boundary on the size of a string; the only limit is the available memory of the computer on which PHP is running. Syntax A string literal can be specified in four different ways: * single quoted * double quoted * heredoc syntax * nowdoc syntax (since PHP 5.3.0) Single quoted The simplest way to specify a string is to enclose it in single quotes (the character '). To specify a literal single quote, escape it with a backslash (\). To specify a literal backslash, double it (\\). All other instances of backslash will be treated as a literal backslash: this means that the other escape sequences you might be used to, such as \r or \n, will be output literally as specified rather than having any special meaning. Note: Unlike the double-quoted and heredoc syntaxes, variables and escape sequences for special characters will not be expanded when they occur in single quoted strings. Double quoted If the string is enclosed in double-quotes ("), PHP will interpret more escape sequences for special characters: Escaped characters Sequence Meaning \n linefeed (LF or 0x0A (10) in ASCII) \r carriage return (CR or 0x0D (13) in ASCII) \t horizontal tab (HT or 0x09 (9) in ASCII) \v vertical tab (VT or 0x0B (11) in ASCII) (since PHP 5.2.5) \f form feed (FF or 0x0C (12) in ASCII) (since PHP 5.2.5) \\ backslash \$ dollar sign \" double-quote \[0-7]{1,3} the sequence of characters matching the regular expression is a character in octal notation \x[0-9A-Fa-f]{1,2} the sequence of characters matching the regular expression is a character in hexadecimal notation As in single quoted strings, escaping any other character will result in the backslash being printed too. Before PHP 5.1.1, the backslash in \{$var} had not been printed. The most important feature of double-quoted strings is the fact that variable names will be expanded. See string parsing for details. Heredoc A third way to delimit strings is the heredoc syntax: <<<. After this operator, an identifier is provided, then a newline. The string itself follows, and then the same identifier again to close the quotation. The closing identifier must begin in the first column of the line. Also, the identifier must follow the same naming rules as any other label in PHP: it must contain only alphanumeric characters and underscores, and must start with a non-digit character or underscore. Warning It is very important to note that the line with the closing identifier must contain no other characters, except possibly a semicolon (;). That means especially that the identifier may not be indented, and there may not be any spaces or tabs before or after the semicolon. It's also important to realize that the first character before the closing identifier must be a newline as defined by the local operating system. This is \n on UNIX systems, including Mac OS X. The closing delimiter (possibly followed by a semicolon) must also be followed by a newline. If this rule is broken and the closing identifier is not "clean", it will not be considered a closing identifier, and PHP will continue looking for one. If a proper closing identifier is not found before the end of the current file, a parse error will result at the last line. Heredocs can not be used for initializing class properties. Since PHP 5.3, this limitation is valid only for heredocs containing variables. Example #1 Invalid example Heredoc text behaves just like a double-quoted string, without the double quotes. This means that quotes in a heredoc do not need to be escaped, but the escape codes listed above can still be used. Variables are expanded, but the same care must be taken when expressing complex variables inside a heredoc as with strings. Example #2 Heredoc string quoting example foo = 'Foo'; $this->bar = array('Bar1', 'Bar2', 'Bar3'); } } $foo = new foo(); $name = 'MyName'; echo <<foo. Now, I am printing some {$foo->bar[1]}. This should print a capital 'A': \x41 EOT; ?> The above example will output: My name is "MyName". I am printing some Foo. Now, I am printing some Bar2. This should print a capital 'A': A It is also possible to use the Heredoc syntax to pass data to function arguments: Example #3 Heredoc in arguments example As of PHP 5.3.0, it's possible to initialize static variables and class properties/constants using the Heredoc syntax: Example #4 Using Heredoc to initialize static values Starting with PHP 5.3.0, the opening Heredoc identifier may optionally be enclosed in double quotes: Example #5 Using double quotes in Heredoc Note: Heredoc support was added in PHP 4. Nowdoc Nowdocs are to single-quoted strings what heredocs are to double-quoted strings. A nowdoc is specified similarly to a heredoc, but no parsing is done inside a nowdoc. The construct is ideal for embedding PHP code or other large blocks of text without the need for escaping. It shares some features in common with the SGML construct, in that it declares a block of text which is not for parsing. A nowdoc is identified with the same <<< sequence used for heredocs, but the identifier which follows is enclosed in single quotes, e.g. <<<'EOT'. All the rules for heredoc identifiers also apply to nowdoc identifiers, especially those regarding the appearance of the closing identifier. Example #6 Nowdoc string quoting example foo = 'Foo'; $this->bar = array('Bar1', 'Bar2', 'Bar3'); } } $foo = new foo(); $name = 'MyName'; echo <<<'EOT' My name is "$name". I am printing some $foo->foo. Now, I am printing some {$foo->bar[1]}. This should not print a capital 'A': \x41 EOT; ?> The above example will output: My name is "$name". I am printing some $foo->foo. Now, I am printing some {$foo->bar[1]}. This should not print a capital 'A': \x41 Note: Unlike heredocs, nowdocs can be used in any static data context. The typical example is initializing class properties or constants: Example #7 Static data example Note: Nowdoc support was added in PHP 5.3.0. Variable parsing When a string is specified in double quotes or with heredoc, variables are parsed within it. There are two types of syntax: a simple one and a complex one. The simple syntax is the most common and convenient. It provides a way to embed a variable, an array value, or an object property in a string with a minimum of effort. The complex syntax was introduced in PHP 4, and can be recognised by the curly braces surrounding the expression. Simple syntax If a dollar sign ($) is encountered, the parser will greedily take as many tokens as possible to form a valid variable name. Enclose the variable name in curly braces to explicitly specify the end of the name. The above example will output: He drank some apple juice. He drank some juice made of . Similarly, an array index or an object property can be parsed. With array indices, the closing square bracket (]) marks the end of the index. The same rules apply to object properties as to simple variables. Example #8 Simple syntax example "purple"); echo "He drank some $juices[0] juice.".PHP_EOL; echo "He drank some $juices[1] juice.".PHP_EOL; echo "He drank some juice made of $juice[0]s.".PHP_EOL; // Won't work echo "He drank some $juices[koolaid1] juice.".PHP_EOL; class people { public $john = "John Smith"; public $jane = "Jane Smith"; public $robert = "Robert Paulsen"; public $smith = "Smith"; } $people = new people(); echo "$people->john drank some $juices[0] juice.".PHP_EOL; echo "$people->john then said hello to $people->jane.".PHP_EOL; echo "$people->john's wife greeted $people->robert.".PHP_EOL; echo "$people->robert greeted the two $people->smiths."; // Won't work ?> The above example will output: He drank some apple juice. He drank some orange juice. He drank some juice made of s. He drank some purple juice. John Smith drank some apple juice. John Smith then said hello to Jane Smith. John Smith's wife greeted Robert Paulsen. Robert Paulsen greeted the two . For anything more complex, you should use the complex syntax. Complex (curly) syntax This isn't called complex because the syntax is complex, but because it allows for the use of complex expressions. Any scalar variable, array element or object property with a string representation can be included via this syntax. Simply write the expression the same way as it would appear outside the string, and then wrap it in { and }. Since { can not be escaped, this syntax will only be recognised when the $ immediately follows the {. Use {\$ to get a literal {$. Some examples to make it clear: width}00 centimeters broad."; // Works, quoted keys only work using the curly brace syntax echo "This works: {$arr['key']}"; // Works echo "This works: {$arr[4][3]}"; // This is wrong for the same reason as $foo[bar] is wrong outside a string. // In other words, it will still work, but only because PHP first looks for a // constant named foo; an error of level E_NOTICE (undefined constant) will be // thrown. echo "This is wrong: {$arr[foo][3]}"; // Works. When using multi-dimensional arrays, always use braces around arrays // when inside of strings echo "This works: {$arr['foo'][3]}"; // Works. echo "This works: " . $arr['foo'][3]; echo "This works too: {$obj->values[3]->name}"; echo "This is the value of the var named $name: {${$name}}"; echo "This is the value of the var named by the return value of getName(): {${getName()}}"; echo "This is the value of the var named by the return value of \$object->getName(): {${$object->getName()}}"; // Won't work, outputs: This is the return value of getName(): {getName()} echo "This is the return value of getName(): {getName()}"; ?> It is also possible to access class properties using variables within strings using this syntax. $bar}\n"; echo "{$foo->$baz[1]}\n"; ?> The above example will output: I am bar. I am bar. Note: Functions, method calls, static class variables, and class constants inside {$} work since PHP 5. However, the value accessed will be interpreted as the name of a variable in the scope in which the string is defined. Using single curly braces ({}) will not work for accessing the return values of functions or methods or the values of class constants or static class variables. String access and modification by character Characters within strings may be accessed and modified by specifying the zero-based offset of the desired character after the string using square array brackets, as in $str[42]. Think of a string as an array of characters for this purpose. The functions substr() and substr_replace() can be used when you want to extract or replace more than 1 character. Note: Strings may also be accessed using braces, as in $str{42}, for the same purpose. Warning Writing to an out of range offset pads the string with spaces. Non-integer types are converted to integer. Illegal offset type emits E_NOTICE. Negative offset emits E_NOTICE in write but reads empty string. Only the first character of an assigned string is used. Assigning empty string assigns NULL byte. Example #9 Some string examples Note: Accessing variables of other types (not including arrays or objects implementing the appropriate interfaces) using [] or {} silently returns NULL. Useful functions and operators Strings may be concatenated using the '.' (dot) operator. Note that the '+' (addition) operator will not work for this. See String operators for more information. There are a number of useful functions for string manipulation. See the string functions section for general functions, and the regular expression functions or the Perl-compatible regular expression functions for advanced find & replace functionality. There are also functions for URL strings, and functions to encrypt/decrypt strings (mcrypt and mhash). Finally, see also the character type functions. Converting to string A value can be converted to a string using the (string) cast or the strval() function. String conversion is automatically done in the scope of an expression where a string is needed. This happens when using the echo() or print() functions, or when a variable is compared to a string. The sections on Types and Type Juggling will make the following clearer. See also the settype() function. A boolean TRUE value is converted to the string "1". Boolean FALSE is converted to "" (the empty string). This allows conversion back and forth between boolean and string values. An integer or float is converted to a string representing the number textually (including the exponent part for floats). Floating point numbers can be converted using exponential notation (4.1E+6). Note: The decimal point character is defined in the script's locale (category LC_NUMERIC). See the setlocale() function. Arrays are always converted to the string "Array"; because of this, echo() and print() can not by themselves show the contents of an array. To view a single element, use a construction such as echo $arr['foo']. See below for tips on viewing the entire contents. Objects in PHP 4 are always converted to the string "Object". To print the values of object properties for debugging reasons, read the paragraphs below. To get an object's class name, use the get_class() function. As of PHP 5, the __toString method is used when applicable. Resources are always converted to strings with the structure "Resource id #1", where 1 is the unique number assigned to the resource by PHP at runtime. Do not rely upon this structure; it is subject to change. To get a resource's type, use the get_resource_type() function. NULL is always converted to an empty string. As stated above, directly converting an array, object, or resource to a string does not provide any useful information about the value beyond its type. See the functions print_r() and var_dump() for more effective means of inspecting the contents of these types. Most PHP values can also be converted to strings for permanent storage. This method is called serialization, and is performed by the serialize() function. If the PHP engine was built with WDDX support, PHP values can also be serialized as well-formed XML text. String conversion to numbers When a string is evaluated in a numeric context, the resulting value and type are determined as follows. If the string does not contain any of the characters '.', 'e', or 'E' and the numeric value fits into integer type limits (as defined by PHP_INT_MAX), the string will be evaluated as an integer. In all other cases it will be evaluated as a float. The value is given by the initial portion of the string. If the string starts with valid numeric data, this will be the value used. Otherwise, the value will be 0 (zero). Valid numeric data is an optional sign, followed by one or more digits (optionally containing a decimal point), followed by an optional exponent. The exponent is an 'e' or 'E' followed by one or more digits. For more information on this conversion, see the Unix manual page for strtod(3). To test any of the examples in this section, cut and paste the examples and insert the following line to see what's going on: \n"; ?> Do not expect to get the code of one character by converting it to integer, as is done in C. Use the ord() and chr() functions to convert between ASCII codes and characters. ---------------------------------------------------------------------- ---------------------------------------------------------------------- Arrays An array in PHP is actually an ordered map. A map is a type that associates values to keys. This type is optimized for several different uses; it can be treated as an array, list (vector), hash table (an implementation of a map), dictionary, collection, stack, queue, and probably more. As array values can be other arrays, trees and multidimensional arrays are also possible. Explanation of those data structures is beyond the scope of this manual, but at least one example is provided for each of them. For more information, look towards the considerable literature that exists about this broad topic. Syntax Specifying with array() An array can be created by the array() language construct. It takes as parameters any number of comma-separated key => value pairs. array( key => value , ... ) // key may only be an integer or string // value may be any value of any type "bar", 12 => true); echo $arr["foo"]; // bar echo $arr[12]; // 1 ?> A key may be either an integer or a string. If a key is the standard representation of an integer, it will be interpreted as such (i.e. "8" will be interpreted as 8, while "08" will be interpreted as "08"). Floats in key are truncated to integer. The indexed and associative array types are the same type in PHP, which can both contain integer and string indices. A value can be any PHP type. Note: Attempting to access an array key which has not been defined is the same as accessing any other undefined variable: an E_NOTICE-level error message will be issued, and the result will be NULL. array(6 => 5, 13 => 9, "a" => 42)); echo $arr["somearray"][6]; // 5 echo $arr["somearray"][13]; // 9 echo $arr["somearray"]["a"]; // 42 ?> If a key is not specified for a value, the maximum of the integer indices is taken and the new key will be that value plus 1. If a key that already has an assigned value is specified, that value will be overwritten. 43, 32, 56, "b" => 12); // ...this array array(5 => 43, 6 => 32, 7 => 56, "b" => 12); ?> Warning Before PHP 4.3.0, appending to an array in which the current maximum key was negative would create a new key as described above. Since PHP 4.3.0, the new key will be 0. Using TRUE as key will evaluate to integer 1 as a key. Using FALSE as key will evaluate to integer 0 as a key. Using NULL as a key will evaluate to the empty string. Using the empty string as a key will create (or overwrite) a key with the empty string and its value; it is not the same as using empty brackets. Arrays and objects can not be used as keys. Doing so will result in a warning: Illegal offset type. Creating/modifying with square bracket syntax An existing array can be modified by explicitly setting values in it. This is done by assigning values to the array, specifying the key in brackets. The key can also be omitted, resulting in an empty pair of brackets ([]). $arr[key] = value; $arr[] = value; // key may be an integer or string // value may be any value of any type If $arr doesn't exist yet, it will be created, so this is also an alternative way to create an array. To change a certain value, assign a new value to that element using its key. To remove a key/value pair, call the unset() function on it. 1, 12 => 2); $arr[] = 56; // This is the same as $arr[13] = 56; // at this point of the script $arr["x"] = 42; // This adds a new element to // the array with key "x" unset($arr[5]); // This removes the element from the array unset($arr); // This deletes the whole array ?> Note: As mentioned above, if no key is specified, the maximum of the existing integer indices is taken, and the new key will be that maximum value plus 1. If no integer indices exist yet, the key will be 0 (zero). Note that the maximum integer key used for this need not currently exist in the array. It need only have existed in the array at some time since the last time the array was re-indexed. The following example illustrates: $value) { unset($array[$i]); } print_r($array); // Append an item (note that the new key is 5, instead of 0). $array[] = 6; print_r($array); // Re-index: $array = array_values($array); $array[] = 7; print_r($array); ?> The above example will output: Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 [4] => 5 ) Array ( ) Array ( [5] => 6 ) Array ( [0] => 6 [1] => 7 ) Useful functions There are quite a few useful functions for working with arrays. See the array functions section. Note: The unset() function allows removing keys from an array. Be aware that the array will not be reindexed. If a true "remove and shift" behavior is desired, the array can be reindexed using the array_values() function. 'one', 2 => 'two', 3 => 'three'); unset($a[2]); /* will produce an array that would have been defined as $a = array(1 => 'one', 3 => 'three'); and NOT $a = array(1 => 'one', 2 =>'three'); */ $b = array_values($a); // Now $b is array(0 => 'one', 1 =>'three') ?> The foreach control structure exists specifically for arrays. It provides an easy way to traverse an array. Array do's and don'ts Why is $foo[bar] wrong? Always use quotes around a string literal array index. For example, $foo['bar'] is correct, while $foo[bar] is not. But why? It is common to encounter this kind of syntax in old scripts: This is wrong, but it works. The reason is that this code has an undefined constant (bar) rather than a string ('bar' - notice the quotes). PHP may in future define constants which, unfortunately for such code, have the same name. It works because PHP automatically converts a bare string (an unquoted string which does not correspond to any known symbol) into a string which contains the bare string. For instance, if there is no defined constant named bar, then PHP will substitute in the string 'bar' and use that. Note: This does not mean to always quote the key. Do not quote keys which are constants or variables, as this will prevent PHP from interpreting them. The above example will output: Checking 0: Notice: Undefined index: $i in /path/to/script.html on line 9 Bad: Good: 1 Notice: Undefined index: $i in /path/to/script.html on line 11 Bad: Good: 1 Checking 1: Notice: Undefined index: $i in /path/to/script.html on line 9 Bad: Good: 2 Notice: Undefined index: $i in /path/to/script.html on line 11 Bad: Good: 2 More examples to demonstrate this behaviour: 'apple', 'veggie' => 'carrot'); // Correct print $arr['fruit']; // apple print $arr['veggie']; // carrot // Incorrect. This works but also throws a PHP error of level E_NOTICE because // of an undefined constant named fruit // // Notice: Use of undefined constant fruit - assumed 'fruit' in... print $arr[fruit]; // apple // This defines a constant to demonstrate what's going on. The value 'veggie' // is assigned to a constant named fruit. define('fruit', 'veggie'); // Notice the difference now print $arr['fruit']; // apple print $arr[fruit]; // carrot // The following is okay, as it's inside a string. Constants are not looked for // within strings, so no E_NOTICE occurs here print "Hello $arr[fruit]"; // Hello apple // With one exception: braces surrounding arrays within strings allows constants // to be interpreted print "Hello {$arr[fruit]}"; // Hello carrot print "Hello {$arr['fruit']}"; // Hello apple // This will not work, and will result in a parse error, such as: // Parse error: parse error, expecting T_STRING' or T_VARIABLE' or T_NUM_STRING' // This of course applies to using superglobals in strings as well print "Hello $arr['fruit']"; print "Hello $_GET['foo']"; // Concatenation is another option print "Hello " . $arr['fruit']; // Hello apple ?> When error_reporting is set to show E_NOTICE level errors (by setting it to E_ALL, for example), such uses will become immediately visible. By default, error_reporting is set not to show notices. As stated in the syntax section, what's inside the square brackets ('[' and ']') must be an expression. This means that code like this works: This is an example of using a function return value as the array index. PHP also knows about constants: Note that E_ERROR is also a valid identifier, just like bar in the first example. But the last example is in fact the same as writing: because E_ERROR equals 1, etc. So why is it bad then? At some point in the future, the PHP team might want to add another constant or keyword, or a constant in other code may interfere. For example, it is already wrong to use the words empty and default this way, since they are reserved keywords. Note: To reiterate, inside a double-quoted string, it's valid to not surround array indexes with quotes so "$foo[bar]" is valid. See the above examples for details on why as well as the section on variable parsing in strings. Converting to array For any of the types: integer, float, string, boolean and resource, converting a value to an array results in an array with a single element with index zero and the value of the scalar which was converted. In other words, (array)$scalarValue is exactly the same as array($scalarValue). If an object is converted to an array, the result is an array whose elements are the object's properties. The keys are the member variable names, with a few notable exceptions: integer properties are unaccessible; private variables have the class name prepended to the variable name; protected variables have a '*' prepended to the variable name. These prepended values have null bytes on either side. This can result in some unexpected behaviour: The above will appear to have two keys named 'AA', although one of them is actually named '\0A\0A'. Converting NULL to an array results in an empty array. Comparing It is possible to compare arrays with the array_diff() function and with array operators. Examples The array type in PHP is very versatile. Here are some examples: 'red', 'taste' => 'sweet', 'shape' => 'round', 'name' => 'apple', 4 // key will be 0 ); $b = array('a', 'b', 'c'); // . . .is completely equivalent with this: $a = array(); $a['color'] = 'red'; $a['taste'] = 'sweet'; $a['shape'] = 'round'; $a['name'] = 'apple'; $a[] = 4; // key will be 0 $b = array(); $b[] = 'a'; $b[] = 'b'; $b[] = 'c'; // After the above code is executed, $a will be the array // array('color' => 'red', 'taste' => 'sweet', 'shape' => 'round', // 'name' => 'apple', 0 => 4), and $b will be the array // array(0 => 'a', 1 => 'b', 2 => 'c'), or simply array('a', 'b', 'c'). ?> Example #1 Using array() 4, 'OS' => 'Linux', 'lang' => 'english', 'short_tags' => true ); // strictly numerical keys $array = array( 7, 8, 0, 156, -10 ); // this is the same as array(0 => 7, 1 => 8, ...) $switching = array( 10, // key = 0 5 => 6, 3 => 7, 'a' => 4, 11, // key = 6 (maximum of integer-indices was 5) '8' => 2, // key = 8 (integer!) '02' => 77, // key = '02' 0 => 12 // the value 10 will be overwritten by 12 ); // empty array $empty = array(); ?> Example #2 Collection The above example will output: Do you like red? Do you like blue? Do you like green? Do you like yellow? Changing the values of the array directly is possible since PHP 5 by passing them by reference. Before that, a workaround is necessary: Example #3 Changing element in the loop $color) { $colors[$key] = strtoupper($color); } print_r($colors); ?> The above example will output: Array ( [0] => RED [1] => BLUE [2] => GREEN [3] => YELLOW ) This example creates a one-based array. Example #4 One-based index 'January', 'February', 'March'); print_r($firstquarter); ?> The above example will output: Array ( [1] => 'January' [2] => 'February' [3] => 'March' ) Example #5 Filling an array Arrays are ordered. The order can be changed using various sorting functions. See the array functions section for more information. The count() function can be used to count the number of items in an array. Example #6 Sorting an array Because the value of an array can be anything, it can also be another array. This enables the creation of recursive and multi-dimensional arrays. Example #7 Recursive and multi-dimensional arrays array ( "a" => "orange", "b" => "banana", "c" => "apple" ), "numbers" => array ( 1, 2, 3, 4, 5, 6 ), "holes" => array ( "first", 5 => "second", "third" ) ); // Some examples to address values in the array above echo $fruits["holes"][5]; // prints "second" echo $fruits["fruits"]["a"]; // prints "orange" unset($fruits["holes"][0]); // remove "first" // Create a new multi-dimensional array $juices["apple"]["green"] = "good"; ?> Array assignment always involves value copying. Use the reference operator to copy an array by reference. ---------------------------------------------------------------------- ---------------------------------------------------------------------- Objects Object Initialization To create a new object, use the new statement to instantiate a class: do_foo(); ?> For a full discussion, see the Classes and Objects chapter. Converting to object If an object is converted to an object, it is not modified. If a value of any other type is converted to an object, a new instance of the stdClass built-in class is created. If the value was NULL, the new instance will be empty. Arrays convert to an object with properties named by keys, and corresponding values. For any other value, a member variable named scalar will contain the value. scalar; // outputs 'ciao' ?> ---------------------------------------------------------------------- ---------------------------------------------------------------------- Resources A resource is a special variable, holding a reference to an external resource. Resources are created and used by special functions. See the appendix for a listing of all these functions and the corresponding resource types. Note: The resource type was introduced in PHP 4 See also the get_resource_type() function. Converting to resource As resource variables hold special handlers to opened files, database connections, image canvas areas and the like, converting to a resource makes no sense. Freeing resources Thanks to the reference-counting system introduced with PHP 4's Zend Engine, a resource with no more references to it is detected automatically, and it is freed by the garbage collector. For this reason, it is rarely necessary to free the memory manually. Note: Persistent database links are an exception to this rule. They are not destroyed by the garbage collector. See the persistent connections section for more information. ---------------------------------------------------------------------- ---------------------------------------------------------------------- NULL The special NULL value represents a variable with no value. NULL is the only possible value of type NULL. Note: The null type was introduced in PHP 4. A variable is considered to be null if: * it has been assigned the constant NULL. * it has not been set to any value yet. * it has been unset(). Syntax There is only one value of type null, and that is the case-insensitive keyword NULL. See also the functions is_null() and unset(). Casting to NULL Casting a variable to null will remove the variable and unset its value. ---------------------------------------------------------------------- ---------------------------------------------------------------------- Pseudo-types and variables used in this documentation mixed mixed indicates that a parameter may accept multiple (but not necessarily all) types. gettype() for example will accept all PHP types, while str_replace() will accept strings and arrays. number number indicates that a parameter can be either integer or float. callback Some functions like call_user_func() or usort() accept user-defined callback functions as a parameter. Callback functions can not only be simple functions, but also object methods, including static class methods. A PHP function is passed by its name as a string. Any built-in or user-defined function can be used, except language constructs such as: array(), echo(), empty(), eval(), exit(), isset(), list(), print() or unset(). A method of an instantiated object is passed as an array containing an object at index 0 and the method name at index 1. Static class methods can also be passed without instantiating an object of that class by passing the class name instead of an object at index 0. Apart from common user-defined function, create_function() can also be used to create an anonymous callback function. As of PHP 5.3.0 it is possible to also pass a closure to a callback parameter. Example #1 Callback function examples Example #2 Callback example using a Closure The above example will output: 2 4 6 8 10 Note: In PHP4, it was necessary to use a reference to create a callback that points to the actual object, and not a copy of it. For more details, see References Explained. Note: Callbacks registered with functions such as call_user_func() and call_user_func_array() will not be called if there is an uncaught exception thrown in a previous callback. void void as a return type means that the return value is useless. void in a parameter list means that the function doesn't accept any parameters. ... $... in function prototypes means and so on. This variable name is used when a function can take an endless number of arguments. ---------------------------------------------------------------------- ---------------------------------------------------------------------- Type Juggling PHP does not require (or support) explicit type definition in variable declaration; a variable's type is determined by the context in which the variable is used. That is to say, if a string value is assigned to variable $var, $var becomes a string. If an integer value is then assigned to $var, it becomes an integer. An example of PHP's automatic type conversion is the addition operator '+'. If either operand is a float, then both operands are evaluated as floats, and the result will be a float. Otherwise, the operands will be interpreted as integers, and the result will also be an integer. Note that this does not change the types of the operands themselves; the only change is in how the operands are evaluated and what the type of the expression itself is. If the last two examples above seem odd, see String conversion to numbers. To force a variable to be evaluated as a certain type, see the section on Type casting. To change the type of a variable, see the settype() function. To test any of the examples in this section, use the var_dump() function. Note: The behaviour of an automatic conversion to array is currently undefined. Also, because PHP supports indexing into strings via offsets using the same syntax as array indexing, the following example holds true for all PHP versions: See the section titled String access by character for more information. Type Casting Type casting in PHP works much as it does in C: the name of the desired type is written in parentheses before the variable which is to be cast. The casts allowed are: * (int), (integer) - cast to integer * (bool), (boolean) - cast to boolean * (float), (double), (real) - cast to float * (string) - cast to string * (array) - cast to array * (object) - cast to object * (unset) - cast to NULL (PHP 5) (binary) casting and b prefix forward support was added in PHP 5.2.1 Note that tabs and spaces are allowed inside the parentheses, so the following are functionally equivalent: Casting literal strings and variables to binary strings: Note: Instead of casting a variable to a string, it is also possible to enclose the variable in double quotes. It may not be obvious exactly what will happen when casting between certain types. For more information, see these sections: * Converting to boolean * Converting to integer * Converting to float * Converting to string * Converting to array * Converting to object * Converting to resource * Converting to NULL * The type comparison tables ---------------------------------------------------------------------- ---------------------------------------------------------------------- ---------------------------------------------------------------------- Variables Table of Contents * Basics * Predefined Variables * Variable scope * Variable variables * Variables From External Sources ---------------------------------------------------------------------- Basics Variables in PHP are represented by a dollar sign followed by the name of the variable. The variable name is case-sensitive. Variable names follow the same rules as other labels in PHP. A valid variable name starts with a letter or underscore, followed by any number of letters, numbers, or underscores. As a regular expression, it would be expressed thus: '[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*' Note: For our purposes here, a letter is a-z, A-Z, and the bytes from 127 through 255 (0x7f-0xff). Note: $this is a special variable that can't be assigned. Tip See also the Userland Naming Guide. For information on variable related functions, see the Variable Functions Reference. By default, variables are always assigned by value. That is to say, when you assign an expression to a variable, the entire value of the original expression is copied into the destination variable. This means, for instance, that after assigning one variable's value to another, changing one of those variables will have no effect on the other. For more information on this kind of assignment, see the chapter on Expressions. PHP also offers another way to assign values to variables: assign by reference. This means that the new variable simply references (in other words, "becomes an alias for" or "points to") the original variable. Changes to the new variable affect the original, and vice versa. To assign by reference, simply prepend an ampersand (&) to the beginning of the variable which is being assigned (the source variable). For instance, the following code snippet outputs 'My name is Bob' twice: One important thing to note is that only named variables may be assigned by reference. It is not necessary to initialize variables in PHP however it is a very good practice. Uninitialized variables have a default value of their type depending on the context in which they are used - booleans default to FALSE, integers and floats default to zero, strings (e.g. used in echo()) are set as an empty string and arrays become to an empty array. Example #1 Default values of uninitialized variables 25 var_dump($unset_int); // Float/double usage; outputs 'float(1.25)' $unset_float += 1.25; var_dump($unset_float); // Array usage; outputs array(1) { [3]=> string(3) "def" } $unset_arr[3] = "def"; // array() + array(3 => "def") => array(3 => "def") var_dump($unset_arr); // Object usage; creates new stdClass object (see http://www.php.net/manual/en/reserved.classes.php) // Outputs: object(stdClass)#1 (1) { ["foo"]=> string(3) "bar" } $unset_obj->foo = 'bar'; var_dump($unset_obj); ?> Relying on the default value of an uninitialized variable is problematic in the case of including one file into another which uses the same variable name. It is also a major security risk with register_globals turned on. E_NOTICE level error is issued in case of working with uninitialized variables, however not in the case of appending elements to the uninitialized array. isset() language construct can be used to detect if a variable has been already initialized. ---------------------------------------------------------------------- ---------------------------------------------------------------------- Predefined Variables PHP provides a large number of predefined variables to any script which it runs. Many of these variables, however, cannot be fully documented as they are dependent upon which server is running, the version and setup of the server, and other factors. Some of these variables will not be available when PHP is run on the command line. For a listing of these variables, please see the section on Reserved Predefined Variables. Warning In PHP 4.2.0 and later, the default value for the PHP directive register_globals is off. This is a major change in PHP. Having register_globals off affects the set of predefined variables available in the global scope. For example, to get DOCUMENT_ROOT you'll use $_SERVER['DOCUMENT_ROOT'] instead of $DOCUMENT_ROOT, or $_GET['id'] from the URL http://www.example.com/test.php?id=3 instead of $id, or $_ENV['HOME'] instead of $HOME. For related information on this change, read the configuration entry for register_globals, the security chapter on Using Register Globals , as well as the PHP >> 4.1.0 and >> 4.2.0 Release Announcements. Using the available PHP Reserved Predefined Variables, like the superglobal arrays, is preferred. From version 4.1.0 onward, PHP provides an additional set of predefined arrays containing variables from the web server (if applicable), the environment, and user input. These new arrays are rather special in that they are automatically global--i.e., automatically available in every scope. For this reason, they are often known as "superglobals". (There is no mechanism in PHP for user-defined superglobals.) The superglobals are listed below; however, for a listing of their contents and further discussion on PHP predefined variables and their natures, please see the section Reserved Predefined Variables. Also, you'll notice how the older predefined variables ($HTTP_*_VARS) still exist. As of PHP 5.0.0, the long PHP predefined variable arrays may be disabled with the register_long_arrays directive. Note: Variable variables Superglobals cannot be used as variable variables inside functions or class methods. Note: Even though both the superglobal and HTTP_*_VARS can exist at the same time; they are not identical, so modifying one will not change the other. If certain variables in variables_order are not set, their appropriate PHP predefined arrays are also left empty. ---------------------------------------------------------------------- ---------------------------------------------------------------------- Variable scope The scope of a variable is the context within which it is defined. For the most part all PHP variables only have a single scope. This single scope spans included and required files as well. For example: Here the $a variable will be available within the included b.inc script. However, within user-defined functions a local function scope is introduced. Any variable used inside a function is by default limited to the local function scope. For example: This script will not produce any output because the echo statement refers to a local version of the $a variable, and it has not been assigned a value within this scope. You may notice that this is a little bit different from the C language in that global variables in C are automatically available to functions unless specifically overridden by a local definition. This can cause some problems in that people may inadvertently change a global variable. In PHP global variables must be declared global inside a function if they are going to be used in that function. The global keyword First, an example use of global: Example #1 Using global The above script will output 3. By declaring $a and $b global within the function, all references to either variable will refer to the global version. There is no limit to the number of global variables that can be manipulated by a function. A second way to access variables from the global scope is to use the special PHP-defined $GLOBALS array. The previous example can be rewritten as: Example #2 Using $GLOBALS instead of global The $GLOBALS array is an associative array with the name of the global variable being the key and the contents of that variable being the value of the array element. Notice how $GLOBALS exists in any scope, this is because $GLOBALS is a superglobal. Here's an example demonstrating the power of superglobals: Example #3 Example demonstrating superglobals and scope Note: Using global keyword outside a function is not an error. It can be used if the file is included from inside a function. Using static variables Another important feature of variable scoping is the static variable. A static variable exists only in a local function scope, but it does not lose its value when program execution leaves this scope. Consider the following example: Example #4 Example demonstrating need for static variables This function is quite useless since every time it is called it sets $a to 0 and prints 0. The $a++ which increments the variable serves no purpose since as soon as the function exits the $a variable disappears. To make a useful counting function which will not lose track of the current count, the $a variable is declared static: Example #5 Example use of static variables Now, $a is initialized only in first call of function and every time the test() function is called it will print the value of $a and increment it. Static variables also provide one way to deal with recursive functions. A recursive function is one which calls itself. Care must be taken when writing a recursive function because it is possible to make it recurse indefinitely. You must make sure you have an adequate way of terminating the recursion. The following simple function recursively counts to 10, using the static variable $count to know when to stop: Example #6 Static variables with recursive functions Note: Static variables may be declared as seen in the examples above. Trying to assign values to these variables which are the result of expressions will cause a parse error. Example #7 Declaring static variables Note: Static declarations are resolved in compile-time. Note: Using global keyword outside a function is not an error. It can be used if the file is included from inside a function. References with global and static variables The Zend Engine 1, driving PHP 4, implements the static and global modifier for variables in terms of references. For example, a true global variable imported inside a function scope with the global statement actually creates a reference to the global variable. This can lead to unexpected behaviour which the following example addresses: The above example will output: NULL object(stdClass)(0) { } A similar behaviour applies to the static statement. References are not stored statically: property++; return $obj; } function &get_instance_noref() { static $obj; echo 'Static object: '; var_dump($obj); if (!isset($obj)) { // Assign the object to the static variable $obj = new stdclass; } $obj->property++; return $obj; } $obj1 = get_instance_ref(); $still_obj1 = get_instance_ref(); echo "\n"; $obj2 = get_instance_noref(); $still_obj2 = get_instance_noref(); ?> The above example will output: Static object: NULL Static object: NULL Static object: NULL Static object: object(stdClass)(1) { ["property"]=> int(1) } This example demonstrates that when assigning a reference to a static variable, it's not remembered when you call the &get_instance_ref() function a second time. ---------------------------------------------------------------------- ---------------------------------------------------------------------- Variable variables Sometimes it is convenient to be able to have variable variable names. That is, a variable name which can be set and used dynamically. A normal variable is set with a statement such as: A variable variable takes the value of a variable and treats that as the name of a variable. In the above example, hello, can be used as the name of a variable by using two dollar signs. i.e. At this point two variables have been defined and stored in the PHP symbol tree: $a with contents "hello" and $hello with contents "world". Therefore, this statement: produces the exact same output as: i.e. they both produce: hello world. In order to use variable variables with arrays, you have to resolve an ambiguity problem. That is, if you write $$a[1] then the parser needs to know if you meant to use $a[1] as a variable, or if you wanted $$a as the variable and then the [1] index from that variable. The syntax for resolving this ambiguity is: ${$a[1]} for the first case and ${$a}[1] for the second. Class properties may also be accessed using variable property names. The variable property name will be resolved within the scope from which the call is made. For instance, if you have an expression such as $foo->$bar, then the local scope will be examined for $bar and its value will be used as the name of the property of $foo. This is also true if $bar is an array access. Example #1 Variable function example $bar . "\n"; echo $foo->$baz[1] . "\n"; ?> The above example will output: I am bar. I am bar. Warning Please note that variable variables cannot be used with PHP's Superglobal arrays within functions or class methods. The variable $this is also a special variable that cannot be referenced dynamically. ---------------------------------------------------------------------- ---------------------------------------------------------------------- Variables From External Sources HTML Forms (GET and POST) When a form is submitted to a PHP script, the information from that form is automatically made available to the script. There are many ways to access this information, for example: Example #1 A simple HTML form
Name:
Email:
Depending on your particular setup and personal preferences, there are many ways to access data from your HTML forms. Some examples are: Example #2 Accessing data from a simple POST HTML form Using a GET form is similar except you'll use the appropriate GET predefined variable instead. GET also applies to the QUERY_STRING (the information after the '?' in a URL). So, for example, http://www.example.com/test.php?id=3 contains GET data which is accessible with $_GET['id']. See also $_REQUEST and import_request_variables(). Note: Superglobal arrays, like $_POST and $_GET, became available in PHP 4.1.0 Note: Dots and spaces in variable names are converted to underscores. For example becomes $_REQUEST["a_b"]. As shown, before PHP 4.2.0 the default value for register_globals was on. The PHP community is encouraging all to not rely on this directive as it's preferred to assume it's off and code accordingly. Note: The magic_quotes_gpc configuration directive affects Get, Post and Cookie values. If turned on, value (It's "PHP!") will automagically become (It\'s \"PHP!\"). Escaping is needed for DB insertion. See also addslashes(), stripslashes() and magic_quotes_sybase. PHP also understands arrays in the context of form variables (see the related faq). You may, for example, group related variables together, or use this feature to retrieve values from a multiple select input. For example, let's post a form to itself and upon submission display the data: Example #3 More complex form variables '; echo htmlspecialchars(print_r($_POST, true)); echo ''; } ?>
Name:
Email:
Beer:

IMAGE SUBMIT variable names When submitting a form, it is possible to use an image instead of the standard submit button with a tag like: When the user clicks somewhere on the image, the accompanying form will be transmitted to the server with two additional variables, sub_x and sub_y. These contain the coordinates of the user click within the image. The experienced may note that the actual variable names sent by the browser contains a period rather than an underscore, but PHP converts the period to an underscore automatically. HTTP Cookies PHP transparently supports HTTP cookies as defined by >> Netscape's Spec. Cookies are a mechanism for storing data in the remote browser and thus tracking or identifying return users. You can set cookies using the setcookie() function. Cookies are part of the HTTP header, so the SetCookie function must be called before any output is sent to the browser. This is the same restriction as for the header() function. Cookie data is then available in the appropriate cookie data arrays, such as $_COOKIE, $HTTP_COOKIE_VARS as well as in $_REQUEST. See the setcookie() manual page for more details and examples. If you wish to assign multiple values to a single cookie variable, you may assign it as an array. For example: That will create two separate cookies although MyCookie will now be a single array in your script. If you want to set just one cookie with multiple values, consider using serialize() or explode() on the value first. Note that a cookie will replace a previous cookie by the same name in your browser unless the path or domain is different. So, for a shopping cart application you may want to keep a counter and pass this along. i.e. Example #4 A setcookie() example Dots in incoming variable names Typically, PHP does not alter the names of variables when they are passed into a script. However, it should be noted that the dot (period, full stop) is not a valid character in a PHP variable name. For the reason, look at it: Now, what the parser sees is a variable named $varname, followed by the string concatenation operator, followed by the barestring (i.e. unquoted string which doesn't match any known key or reserved words) 'ext'. Obviously, this doesn't have the intended result. For this reason, it is important to note that PHP will automatically replace any dots in incoming variable names with underscores. Determining variable types Because PHP determines the types of variables and converts them (generally) as needed, it is not always obvious what type a given variable is at any one time. PHP includes several functions which find out what type a variable is, such as: gettype(), is_array(), is_float(), is_int(), is_object(), and is_string(). See also the chapter on Types. ---------------------------------------------------------------------- ---------------------------------------------------------------------- ---------------------------------------------------------------------- Constants Table of Contents * Syntax * Magic constants A constant is an identifier (name) for a simple value. As the name suggests, that value cannot change during the execution of the script (except for magic constants, which aren't actually constants). A constant is case-sensitive by default. By convention, constant identifiers are always uppercase. The name of a constant follows the same rules as any label in PHP. A valid constant name starts with a letter or underscore, followed by any number of letters, numbers, or underscores. As a regular expression, it would be expressed thusly: [a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]* Tip See also the Userland Naming Guide. Example #1 Valid and invalid constant names Note: For our purposes here, a letter is a-z, A-Z, and the ASCII characters from 127 through 255 (0x7f-0xff). Like superglobals, the scope of a constant is global. You can access constants anywhere in your script without regard to scope. For more information on scope, read the manual section on variable scope. ---------------------------------------------------------------------- Syntax You can define a constant by using the define()-function or by using the const keyword outside a class definition as of PHP 5.3.0. Once a constant is defined, it can never be changed or undefined. Only scalar data (boolean, integer, float and string) can be contained in constants. It is possible to define constants as a resource, but it should be avoided, as it can cause unexpected results. You can get the value of a constant by simply specifying its name. Unlike with variables, you should not prepend a constant with a $. You can also use the function constant() to read a constant's value if you wish to obtain the constant's name dynamically. Use get_defined_constants() to get a list of all defined constants. Note: Constants and (global) variables are in a different namespace. This implies that for example TRUE and $TRUE are generally different. If you use an undefined constant, PHP assumes that you mean the name of the constant itself, just as if you called it as a string (CONSTANT vs "CONSTANT"). An error of level E_NOTICE will be issued when this happens. See also the manual entry on why $foo[bar] is wrong (unless you first define() bar as a constant). If you simply want to check if a constant is set, use the defined() function. These are the differences between constants and variables: * Constants do not have a dollar sign ($) before them; * Constants may only be defined using the define() function, not by simple assignment; * Constants may be defined and accessed anywhere without regard to variable scoping rules; * Constants may not be redefined or undefined once they have been set; and * Constants may only evaluate to scalar values. Example #1 Defining Constants Example #2 Defining Constants using the const keyword Note: As opposed to defining constants using define(), constants defined using the const keyword must be declared at the top-level scope because they are defined at compile-time. This means that they cannot be declared inside functions, loops or if statements. See also Class Constants. ---------------------------------------------------------------------- ---------------------------------------------------------------------- Magic constants PHP provides a large number of predefined constants to any script which it runs. Many of these constants, however, are created by various extensions, and will only be present when those extensions are available, either via dynamic loading or because they have been compiled in. There are seven magical constants that change depending on where they are used. For example, the value of __LINE__ depends on the line that it's used on in your script. These special constants are case-insensitive and are as follows: A few "magical" PHP constants Name Description __LINE__ The current line number of the file. The full path and filename of the file. If used inside an include, the name of the included file is returned. Since __FILE__ PHP 4.0.2, __FILE__ always contains an absolute path with symlinks resolved whereas in older versions it contained relative path under some circumstances. The directory of the file. If used inside an include, the directory of the included file is returned. This is __DIR__ equivalent to dirname(__FILE__). This directory name does not have a trailing slash unless it is the root directory. (Added in PHP 5.3.0.) The function name. (Added in PHP 4.3.0) As of PHP 5 this __FUNCTION__ constant returns the function name as it was declared (case-sensitive). In PHP 4 its value is always lowercased. The class name. (Added in PHP 4.3.0) As of PHP 5 this __CLASS__ constant returns the class name as it was declared (case-sensitive). In PHP 4 its value is always lowercased. __METHOD__ The class method name. (Added in PHP 5.0.0) The method name is returned as it was declared (case-sensitive). __NAMESPACE__ The name of the current namespace (case-sensitive). This constant is defined in compile-time (Added in PHP 5.3.0). See also get_class(), get_object_vars(), file_exists() and function_exists(). ---------------------------------------------------------------------- ---------------------------------------------------------------------- ---------------------------------------------------------------------- Expressions Expressions are the most important building stones of PHP. In PHP, almost anything you write is an expression. The simplest yet most accurate way to define an expression is "anything that has a value". The most basic forms of expressions are constants and variables. When you type "$a = 5", you're assigning '5' into $a. '5', obviously, has the value 5, or in other words '5' is an expression with the value of 5 (in this case, '5' is an integer constant). After this assignment, you'd expect $a's value to be 5 as well, so if you wrote $b = $a, you'd expect it to behave just as if you wrote $b = 5. In other words, $a is an expression with the value of 5 as well. If everything works right, this is exactly what will happen. Slightly more complex examples for expressions are functions. For instance, consider the following function: Assuming you're familiar with the concept of functions (if you're not, take a look at the chapter about functions), you'd assume that typing $c = foo() is essentially just like writing $c = 5, and you're right. Functions are expressions with the value of their return value. Since foo() returns 5, the value of the expression 'foo()' is 5. Usually functions don't just return a static value but compute something. Of course, values in PHP don't have to be integers, and very often they aren't. PHP supports four scalar value types: integer values, floating point values (float), string values and boolean values (scalar values are values that you can't 'break' into smaller pieces, unlike arrays, for instance). PHP also supports two composite (non-scalar) types: arrays and objects. Each of these value types can be assigned into variables or returned from functions. PHP takes expressions much further, in the same way many other languages do. PHP is an expression-oriented language, in the sense that almost everything is an expression. Consider the example we've already dealt with, '$a = 5'. It's easy to see that there are two values involved here, the value of the integer constant '5', and the value of $a which is being updated to 5 as well. But the truth is that there's one additional value involved here, and that's the value of the assignment itself. The assignment itself evaluates to the assigned value, in this case 5. In practice, it means that '$a = 5', regardless of what it does, is an expression with the value 5. Thus, writing something like '$b = ($a = 5)' is like writing '$a = 5; $b = 5;' (a semicolon marks the end of a statement). Since assignments are parsed in a right to left order, you can also write '$b = $a = 5'. Another good example of expression orientation is pre- and post-increment and decrement. Users of PHP and many other languages may be familiar with the notation of variable++ and variable--. These are increment and decrement operators. In PHP, like in C, there are two types of increment - pre-increment and post-increment. Both pre-increment and post-increment essentially increment the variable, and the effect on the variable is identical. The difference is with the value of the increment expression. Pre-increment, which is written '++$variable', evaluates to the incremented value (PHP increments the variable before reading its value, thus the name 'pre-increment'). Post-increment, which is written '$variable++' evaluates to the original value of $variable, before it was incremented (PHP increments the variable after reading its value, thus the name 'post-increment'). A very common type of expressions are comparison expressions. These expressions evaluate to either FALSE or TRUE. PHP supports > (bigger than), >= (bigger than or equal to), == (equal), != (not equal), < (smaller than) and <= (smaller than or equal to). The language also supports a set of strict equivalence operators: === (equal to and same type) and !== (not equal to or not same type). These expressions are most commonly used inside conditional execution, such as if statements. The last example of expressions we'll deal with here is combined operator-assignment expressions. You already know that if you want to increment $a by 1, you can simply write '$a++' or '++$a'. But what if you want to add more than one to it, for instance 3? You could write '$a++' multiple times, but this is obviously not a very efficient or comfortable way. A much more common practice is to write '$a = $a + 3'. '$a + 3' evaluates to the value of $a plus 3, and is assigned back into $a, which results in incrementing $a by 3. In PHP, as in several other languages like C, you can write this in a shorter way, which with time would become clearer and quicker to understand as well. Adding 3 to the current value of $a can be written '$a += 3'. This means exactly "take the value of $a, add 3 to it, and assign it back into $a". In addition to being shorter and clearer, this also results in faster execution. The value of '$a += 3', like the value of a regular assignment, is the assigned value. Notice that it is NOT 3, but the combined value of $a plus 3 (this is the value that's assigned into $a). Any two-place operator can be used in this operator-assignment mode, for example '$a -= 5' (subtract 5 from the value of $a), '$b *= 7' (multiply the value of $b by 7), etc. There is one more expression that may seem odd if you haven't seen it in other languages, the ternary conditional operator: If the value of the first subexpression is TRUE (non-zero), then the second subexpression is evaluated, and that is the result of the conditional expression. Otherwise, the third subexpression is evaluated, and that is the value. The following example should help you understand pre- and post-increment and expressions in general a bit better: Some expressions can be considered as statements. In this case, a statement has the form of 'expr ;' that is, an expression followed by a semicolon. In '$b = $a = 5;', '$a = 5' is a valid expression, but it's not a statement by itself. '$b = $a = 5;' however is a valid statement. One last thing worth mentioning is the truth value of expressions. In many events, mainly in conditional execution and loops, you're not interested in the specific value of the expression, but only care about whether it means TRUE or FALSE. The constants TRUE and FALSE (case-insensitive) are the two possible boolean values. When necessary, an expression is automatically converted to boolean. See the section about type-casting for details about how. PHP provides a full and powerful implementation of expressions, and documenting it entirely goes beyond the scope of this manual. The above examples should give you a good idea about what expressions are and how you can construct useful expressions. Throughout the rest of this manual we'll write expr to indicate any valid PHP expression. ---------------------------------------------------------------------- ---------------------------------------------------------------------- Operators Table of Contents * Operator Precedence * Arithmetic Operators * Assignment Operators * Bitwise Operators * Comparison Operators * Error Control Operators * Execution Operators * Incrementing/Decrementing Operators * Logical Operators * String Operators * Array Operators * Type Operators An operator is something that takes one or more values (or expressions, in programming jargon) and yields another value (so that the construction itself becomes an expression). Operators can be grouped according to the number of values they take. Unary operators take only one value, for example ! (the logical not operator) or ++ (the increment operator). Binary operators take two values, such as the familiar arithmetical operators + (plus) and - (minus), and the majority of PHP operators fall into this category. Finally, there is a single ternary operator, ? :, which takes three values; this is usually referred to simply as "the ternary operator" (although it could perhaps more properly be called the conditional operator). A full list of PHP operators follows in the section Operator Precedence. This also explains operator Presedence and Associativity, which govern exactly how expressions containing several different operators are evaluated. ---------------------------------------------------------------------- Operator Precedence The precedence of an operator specifies how "tightly" it binds two expressions together. For example, in the expression 1 + 5 * 3, the answer is 16 and not 18 because the multiplication ("*") operator has a higher precedence than the addition ("+") operator. Parentheses may be used to force precedence, if necessary. For instance: (1 + 5) * 3 evaluates to 18. When operators have equal precedence, their associativity decides whether they are evaluated starting from the right, or starting from the left - see the examples below. The following table lists the operators in order of precedence, with the highest-precedence ones at the top. Operators on the same line have equal precedence, in which case associativity decides the order of evaluation. Operator Precedence Associativity Operators Additional Information non-associative clone new clone and new left [ array() non-associative ++ -- increment/decrement right ~ - (int) (float) (string) (array) types (object) (bool) @ non-associative instanceof types right ! logical left * / % arithmetic left + - . arithmetic and string left << >> bitwise non-associative < <= > >= <> comparison non-associative == != === !== comparison left & bitwise and references left ^ bitwise left | bitwise left && logical left || logical left ? : ternary right = += -= *= /= .= %= &= |= ^= <<= assignment >>= => left and logical left xor logical left or logical left , many uses For operators of equal precedence, left associativity means that evaluation proceeds from left to right, and right associativity means the opposite. Example #1 Associativity $a = 5, $b = 5 // mixing ++ and + produces undefined behavior $a = 1; echo ++$a + $a++; // may print 4 or 5 ?> Use of parentheses, even when not strictly necessary, can often increase readability of the code. Note: Although = has a lower precedence than most other operators, PHP will still allow expressions similar to the following: if (!$a = foo()), in which case the return value of foo() is put into $a. ---------------------------------------------------------------------- ---------------------------------------------------------------------- Arithmetic Operators Remember basic arithmetic from school? These work just like those. Arithmetic Operators Example Name Result -$a Negation Opposite of $a. $a + $b Addition Sum of $a and $b. $a - $b Subtraction Difference of $a and $b. $a * $b Multiplication Product of $a and $b. $a / $b Division Quotient of $a and $b. $a % $b Modulus Remainder of $a divided by $b. The division operator ("/") returns a float value unless the two operands are integers (or strings that get converted to integers) and the numbers are evenly divisible, in which case an integer value will be returned. Operands of modulus are converted to integers (by stripping the decimal part) before processing. The result of the modulus operator % has the same sign as the dividend - that is, the result of $a % $b will have the same sign as $a. For example: See also the manual page on Math functions. ---------------------------------------------------------------------- ---------------------------------------------------------------------- Assignment Operators The basic assignment operator is "=". Your first inclination might be to think of this as "equal to". Don't. It really means that the left operand gets set to the value of the expression on the rights (that is, "gets set to"). The value of an assignment expression is the value assigned. That is, the value of "$a = 3" is 3. This allows you to do some tricky things: For arrays, assigning a value to a named key is performed using the "=>" operator. The precedence of this operator is the same as other assignment operators. In addition to the basic assignment operator, there are "combined operators" for all of the binary arithmetic, array union and string operators that allow you to use a value in an expression and then set its value to the result of that expression. For example: Note that the assignment copies the original variable to the new one (assignment by value), so changes to one will not affect the other. This may also have relevance if you need to copy something like a large array inside a tight loop. An exception to the usual assignment by value behaviour within PHP occurs with objects, which are assigned by reference in PHP 5. Objects may be explicitly copied via the clone keyword. Assignment by Reference Assignment by reference is also supported, using the "$var = &$othervar;" syntax. Assignment by reference means that both variables end up pointing at the same data, and nothing is copied anywhere. Example #1 Assigning by reference As of PHP 5, the new operator returns a reference automatically, so assigning the result of new by reference results in an E_DEPRECATED message in PHP 5.3 and later, and an E_STRICT message in earlier versions. For example, this code will result in a warning: More information on references and their potential uses can be found in the References Explained section of the manual. ---------------------------------------------------------------------- ---------------------------------------------------------------------- Bitwise Operators Bitwise operators allow evaluation and manipulation of specific bits within an integer. Bitwise Operators Example Name Result $a & $b And Bits that are set in both $a and $b are set. $a | $b Or (inclusive or) Bits that are set in either $a or $b are set. $a ^ $b Xor (exclusive or) Bits that are set in $a or $b but not both are set. ~ $a Not Bits that are set in $a are not set, and vice versa. $a << $b Shift left Shift the bits of $a $b steps to the left (each step means "multiply by two") $a >> $b Shift right Shift the bits of $a $b steps to the right (each step means "divide by two") Bit shifting in PHP is arithmetic. Bits shifted off either end are discarded. Left shifts have zeros shifted in on the right while the sign bit is shifted out on the left, meaning the sign of an operand is not preserved. Right shifts have copies of the sign bit shifted in on the left, meaning the sign of an operand is preserved. Use parentheses to ensure the desired precedence. For example, $a & $b == true evaluates the equivalency then the bitwise and; while ($a & $b) == true evaluates the bitwise and then the equivalency. Be aware of data type conversions. If both the left-hand and right-hand parameters are strings, the bitwise operator will operate on the characters' ASCII values. PHP's error_reporting ini setting uses bitwise values, providing a real-world demonstration of turning bits off. To show all errors, except for notices, the php.ini file instructions say to use: E_ALL & ~E_NOTICE This works by starting with E_ALL: 00000000000000000111011111111111 Then taking the value of E_NOTICE... 00000000000000000000000000001000 ... and inverting it via ~: 11111111111111111111111111110111 Finally, it uses AND (&) to find the bits turned on in both values: 00000000000000000111011111110111 Another way to accomplish that is using XOR (^) to find bits that are on in only one value or the other: E_ALL ^ E_NOTICE error_reporting can also be used to demonstrate turning bits on. The way to show just errors and recoverable errors is: E_ERROR | E_RECOVERABLE_ERROR This process combines E_ERROR 00000000000000000000000000000001 and 00000000000000000001000000000000 using the OR (|) operator to get the bits turned on in either value: 00000000000000000001000000000001 Example #1 Bitwise AND, OR and XOR operations on integers The above example will output: --------- --------- -- --------- result value op test --------- --------- -- --------- Bitwise AND ( 0 = 0000) = ( 0 = 0000) & ( 5 = 0101) ( 1 = 0001) = ( 1 = 0001) & ( 5 = 0101) ( 0 = 0000) = ( 2 = 0010) & ( 5 = 0101) ( 4 = 0100) = ( 4 = 0100) & ( 5 = 0101) ( 0 = 0000) = ( 8 = 1000) & ( 5 = 0101) Bitwise Inclusive OR ( 5 = 0101) = ( 0 = 0000) | ( 5 = 0101) ( 5 = 0101) = ( 1 = 0001) | ( 5 = 0101) ( 7 = 0111) = ( 2 = 0010) | ( 5 = 0101) ( 5 = 0101) = ( 4 = 0100) | ( 5 = 0101) (13 = 1101) = ( 8 = 1000) | ( 5 = 0101) Bitwise Exclusive OR (XOR) ( 5 = 0101) = ( 0 = 0000) ^ ( 5 = 0101) ( 4 = 0100) = ( 1 = 0001) ^ ( 5 = 0101) ( 7 = 0111) = ( 2 = 0010) ^ ( 5 = 0101) ( 1 = 0001) = ( 4 = 0100) ^ ( 5 = 0101) (13 = 1101) = ( 8 = 1000) ^ ( 5 = 0101) Example #2 Bitwise XOR operations on strings Example #3 Bit shifting on integers > $places; p($res, $val, '>>', $places, 'copy of sign bit shifted into left side'); $val = 4; $places = 2; $res = $val >> $places; p($res, $val, '>>', $places); $val = 4; $places = 3; $res = $val >> $places; p($res, $val, '>>', $places, 'bits shift out right side'); $val = 4; $places = 4; $res = $val >> $places; p($res, $val, '>>', $places, 'same result as above; can not shift beyond 0'); echo "\n--- BIT SHIFT RIGHT ON NEGATIVE INTEGERS ---\n"; $val = -4; $places = 1; $res = $val >> $places; p($res, $val, '>>', $places, 'copy of sign bit shifted into left side'); $val = -4; $places = 2; $res = $val >> $places; p($res, $val, '>>', $places, 'bits shift out right side'); $val = -4; $places = 3; $res = $val >> $places; p($res, $val, '>>', $places, 'same result as above; can not shift beyond -1'); echo "\n--- BIT SHIFT LEFT ON POSITIVE INTEGERS ---\n"; $val = 4; $places = 1; $res = $val << $places; p($res, $val, '<<', $places, 'zeros fill in right side'); $val = 4; $places = (PHP_INT_SIZE * 8) - 4; $res = $val << $places; p($res, $val, '<<', $places); $val = 4; $places = (PHP_INT_SIZE * 8) - 3; $res = $val << $places; p($res, $val, '<<', $places, 'sign bits get shifted out'); $val = 4; $places = (PHP_INT_SIZE * 8) - 2; $res = $val << $places; p($res, $val, '<<', $places, 'bits shift out left side'); echo "\n--- BIT SHIFT LEFT ON NEGATIVE INTEGERS ---\n"; $val = -4; $places = 1; $res = $val << $places; p($res, $val, '<<', $places, 'zeros fill in right side'); $val = -4; $places = (PHP_INT_SIZE * 8) - 3; $res = $val << $places; p($res, $val, '<<', $places); $val = -4; $places = (PHP_INT_SIZE * 8) - 2; $res = $val << $places; p($res, $val, '<<', $places, 'bits shift out left side, including sign bit'); /* * Ignore this bottom section, * it is just formatting to make output clearer. */ function p($res, $val, $op, $places, $note = '') { $format = '%0' . (PHP_INT_SIZE * 8) . "b\n"; printf("Expression: %d = %d %s %d\n", $res, $val, $op, $places); echo " Decimal:\n"; printf(" val=%d\n", $val); printf(" res=%d\n", $res); echo " Binary:\n"; printf(' val=' . $format, $val); printf(' res=' . $format, $res); if ($note) { echo " NOTE: $note\n"; } echo "\n"; } ?> Output of the above example on 32 bit machines: --- BIT SHIFT RIGHT ON POSITIVE INTEGERS --- Expression: 2 = 4 >> 1 Decimal: val=4 res=2 Binary: val=00000000000000000000000000000100 res=00000000000000000000000000000010 NOTE: copy of sign bit shifted into left side Expression: 1 = 4 >> 2 Decimal: val=4 res=1 Binary: val=00000000000000000000000000000100 res=00000000000000000000000000000001 Expression: 0 = 4 >> 3 Decimal: val=4 res=0 Binary: val=00000000000000000000000000000100 res=00000000000000000000000000000000 NOTE: bits shift out right side Expression: 0 = 4 >> 4 Decimal: val=4 res=0 Binary: val=00000000000000000000000000000100 res=00000000000000000000000000000000 NOTE: same result as above; can not shift beyond 0 --- BIT SHIFT RIGHT ON NEGATIVE INTEGERS --- Expression: -2 = -4 >> 1 Decimal: val=-4 res=-2 Binary: val=11111111111111111111111111111100 res=11111111111111111111111111111110 NOTE: copy of sign bit shifted into left side Expression: -1 = -4 >> 2 Decimal: val=-4 res=-1 Binary: val=11111111111111111111111111111100 res=11111111111111111111111111111111 NOTE: bits shift out right side Expression: -1 = -4 >> 3 Decimal: val=-4 res=-1 Binary: val=11111111111111111111111111111100 res=11111111111111111111111111111111 NOTE: same result as above; can not shift beyond -1 --- BIT SHIFT LEFT ON POSITIVE INTEGERS --- Expression: 8 = 4 << 1 Decimal: val=4 res=8 Binary: val=00000000000000000000000000000100 res=00000000000000000000000000001000 NOTE: zeros fill in right side Expression: 1073741824 = 4 << 28 Decimal: val=4 res=1073741824 Binary: val=00000000000000000000000000000100 res=01000000000000000000000000000000 Expression: -2147483648 = 4 << 29 Decimal: val=4 res=-2147483648 Binary: val=00000000000000000000000000000100 res=10000000000000000000000000000000 NOTE: sign bits get shifted out Expression: 0 = 4 << 30 Decimal: val=4 res=0 Binary: val=00000000000000000000000000000100 res=00000000000000000000000000000000 NOTE: bits shift out left side --- BIT SHIFT LEFT ON NEGATIVE INTEGERS --- Expression: -8 = -4 << 1 Decimal: val=-4 res=-8 Binary: val=11111111111111111111111111111100 res=11111111111111111111111111111000 NOTE: zeros fill in right side Expression: -2147483648 = -4 << 29 Decimal: val=-4 res=-2147483648 Binary: val=11111111111111111111111111111100 res=10000000000000000000000000000000 Expression: 0 = -4 << 30 Decimal: val=-4 res=0 Binary: val=11111111111111111111111111111100 res=00000000000000000000000000000000 NOTE: bits shift out left side, including sign bit Output of the above example on 64 bit machines: --- BIT SHIFT RIGHT ON POSITIVE INTEGERS --- Expression: 2 = 4 >> 1 Decimal: val=4 res=2 Binary: val=0000000000000000000000000000000000000000000000000000000000000100 res=0000000000000000000000000000000000000000000000000000000000000010 NOTE: copy of sign bit shifted into left side Expression: 1 = 4 >> 2 Decimal: val=4 res=1 Binary: val=0000000000000000000000000000000000000000000000000000000000000100 res=0000000000000000000000000000000000000000000000000000000000000001 Expression: 0 = 4 >> 3 Decimal: val=4 res=0 Binary: val=0000000000000000000000000000000000000000000000000000000000000100 res=0000000000000000000000000000000000000000000000000000000000000000 NOTE: bits shift out right side Expression: 0 = 4 >> 4 Decimal: val=4 res=0 Binary: val=0000000000000000000000000000000000000000000000000000000000000100 res=0000000000000000000000000000000000000000000000000000000000000000 NOTE: same result as above; can not shift beyond 0 --- BIT SHIFT RIGHT ON NEGATIVE INTEGERS --- Expression: -2 = -4 >> 1 Decimal: val=-4 res=-2 Binary: val=1111111111111111111111111111111111111111111111111111111111111100 res=1111111111111111111111111111111111111111111111111111111111111110 NOTE: copy of sign bit shifted into left side Expression: -1 = -4 >> 2 Decimal: val=-4 res=-1 Binary: val=1111111111111111111111111111111111111111111111111111111111111100 res=1111111111111111111111111111111111111111111111111111111111111111 NOTE: bits shift out right side Expression: -1 = -4 >> 3 Decimal: val=-4 res=-1 Binary: val=1111111111111111111111111111111111111111111111111111111111111100 res=1111111111111111111111111111111111111111111111111111111111111111 NOTE: same result as above; can not shift beyond -1 --- BIT SHIFT LEFT ON POSITIVE INTEGERS --- Expression: 8 = 4 << 1 Decimal: val=4 res=8 Binary: val=0000000000000000000000000000000000000000000000000000000000000100 res=0000000000000000000000000000000000000000000000000000000000001000 NOTE: zeros fill in right side Expression: 4611686018427387904 = 4 << 60 Decimal: val=4 res=4611686018427387904 Binary: val=0000000000000000000000000000000000000000000000000000000000000100 res=0100000000000000000000000000000000000000000000000000000000000000 Expression: -9223372036854775808 = 4 << 61 Decimal: val=4 res=-9223372036854775808 Binary: val=0000000000000000000000000000000000000000000000000000000000000100 res=1000000000000000000000000000000000000000000000000000000000000000 NOTE: sign bits get shifted out Expression: 0 = 4 << 62 Decimal: val=4 res=0 Binary: val=0000000000000000000000000000000000000000000000000000000000000100 res=0000000000000000000000000000000000000000000000000000000000000000 NOTE: bits shift out left side --- BIT SHIFT LEFT ON NEGATIVE INTEGERS --- Expression: -8 = -4 << 1 Decimal: val=-4 res=-8 Binary: val=1111111111111111111111111111111111111111111111111111111111111100 res=1111111111111111111111111111111111111111111111111111111111111000 NOTE: zeros fill in right side Expression: -9223372036854775808 = -4 << 61 Decimal: val=-4 res=-9223372036854775808 Binary: val=1111111111111111111111111111111111111111111111111111111111111100 res=1000000000000000000000000000000000000000000000000000000000000000 Expression: 0 = -4 << 62 Decimal: val=-4 res=0 Binary: val=1111111111111111111111111111111111111111111111111111111111111100 res=0000000000000000000000000000000000000000000000000000000000000000 NOTE: bits shift out left side, including sign bit Warning Don't right shift for more than 32 bits on 32 bits systems. Don't left shift in case it results to number longer than 32 bits. Use functions from the gmp extension for bitwise manipulation on numbers beyond PHP_INT_MAX. See also pack(), unpack(), gmp_and(), gmp_or(), gmp_xor(), gmp_testbit(), gmp_clrbit() ---------------------------------------------------------------------- ---------------------------------------------------------------------- Comparison Operators Comparison operators, as their name implies, allow you to compare two values. You may also be interested in viewing the type comparison tables, as they show examples of various type related comparisons. Comparison Operators Example Name Result $a == $b Equal TRUE if $a is equal to $b after type juggling. $a === $b Identical TRUE if $a is equal to $b, and they are of the same type. (introduced in PHP 4) $a != $b Not equal TRUE if $a is not equal to $b after type juggling. $a <> $b Not equal TRUE if $a is not equal to $b after type juggling. TRUE if $a is not equal to $b, or they $a !== $b Not identical are not of the same type. (introduced in PHP 4) $a < $b Less than TRUE if $a is strictly less than $b. $a > $b Greater than TRUE if $a is strictly greater than $b. $a <= $b Less than or equal to TRUE if $a is less than or equal to $b. $a >= $b Greater than or equal TRUE if $a is greater than or equal to to $b. If you compare a number with a string or the comparison involves numerical strings, then each string is converted to a number and the comparison performed numerically. These rules also apply to the switch statement. The type conversion does not take place when the comparison is === or !== as this involves comparing the type as well as the value. true var_dump("1" == "01"); // 1 == 1 -> true var_dump("10" == "1e1"); // 10 == 10 -> true var_dump(100 == "1e2"); // 100 == 100 -> true switch ("a") { case 0: echo "0"; break; case "a": // never reached because "a" is already matched with 0 echo "a"; break; } ?> For various types, comparison is done according to the following table (in order). Comparison with Various Types Type of Operand 1 Type of Operand 2 Result null or string string Convert NULL to "", numerical or lexical comparison bool or null anything Convert to bool, FALSE < TRUE Built-in classes can define its own comparison, different classes are object object uncomparable, same class - compare properties the same way as arrays (PHP 4), PHP 5 has its own explanation string, resource string, resource Translate strings and resources to or number or number numbers, usual math Array with fewer members is smaller, if key from operand 1 is not found in array array operand 2 then arrays are uncomparable, otherwise - compare value by value (see following example) array anything array is always greater object anything object is always greater Example #1 Transcription of standard array comparison count($op2)) { return 1; // $op1 > $op2 } foreach ($op1 as $key => $val) { if (!array_key_exists($key, $op2)) { return null; // uncomparable } elseif ($val < $op2[$key]) { return -1; } elseif ($val > $op2[$key]) { return 1; } } return 0; // $op1 == $op2 } ?> See also strcasecmp(), strcmp(), Array operators, and the manual section on Types. Warning Comparison of floating point numbers Because of the way floats are represented internally, you should not test two floats for equality. See the documentation for float for more information. Ternary Operator Another conditional operator is the "?:" (or ternary) operator. Example #2 Assigning a default value The expression (expr1) ? (expr2) : (expr3) evaluates to expr2 if expr1 evaluates to TRUE, and expr3 if expr1 evaluates to FALSE. Since PHP 5.3, it is possible to leave out the middle part of the ternary operator. Expression expr1 ?: expr3 returns expr1 if expr1 evaluates to TRUE, and expr3 otherwise. Note: Please note that the ternary operator is a statement, and that it doesn't evaluate to a variable, but to the result of a statement. This is important to know if you want to return a variable by reference. The statement return $var == 42 ? $a : $b; in a return-by-reference function will therefore not work and a warning is issued in later PHP versions. Note: It is recommended that you avoid "stacking" ternary expressions. PHP's behaviour when using more than one ternary operator within a single statement is non-obvious: Example #3 Non-obvious Ternary Behaviour ---------------------------------------------------------------------- ---------------------------------------------------------------------- Error Control Operators PHP supports one error control operator: the at sign (@). When prepended to an expression in PHP, any error messages that might be generated by that expression will be ignored. If the track_errors feature is enabled, any error message generated by the expression will be saved in the variable $php_errormsg. This variable will be overwritten on each error, so check early if you want to use it. Note: The @-operator works only on expressions. A simple rule of thumb is: if you can take the value of something, you can prepend the @ operator to it. For instance, you can prepend it to variables, function and include() calls, constants, and so forth. You cannot prepend it to function or class definitions, or conditional structures such as if and foreach, and so forth. See also error_reporting() and the manual section for Error Handling and Logging functions. Warning Currently the "@" error-control operator prefix will even disable error reporting for critical errors that will terminate script execution. Among other things, this means that if you use "@" to suppress errors from a certain function and either it isn't available or has been mistyped, the script will die right there with no indication as to why. ---------------------------------------------------------------------- ---------------------------------------------------------------------- Execution Operators PHP supports one execution operator: backticks (``). Note that these are not single-quotes! PHP will attempt to execute the contents of the backticks as a shell command; the output will be returned (i.e., it won't simply be dumped to output; it can be assigned to a variable). Use of the backtick operator is identical to shell_exec(). $output"; ?> Note: The backtick operator is disabled when safe mode is enabled or shell_exec() is disabled. See also the manual section on Program Execution functions, popen() proc_open(), and Using PHP from the commandline. ---------------------------------------------------------------------- ---------------------------------------------------------------------- Incrementing/Decrementing Operators PHP supports C-style pre- and post-increment and decrement operators. Note: The increment/decrement operators do not affect boolean values. Decrementing NULL values has no effect too, but incrementing them results in 1. Increment/decrement Operators Example Name Effect ++$a Pre-increment Increments $a by one, then returns $a. $a++ Post-increment Returns $a, then increments $a by one. --$a Pre-decrement Decrements $a by one, then returns $a. $a-- Post-decrement Returns $a, then decrements $a by one. Here's a simple example script: Postincrement"; $a = 5; echo "Should be 5: " . $a++ . "
\n"; echo "Should be 6: " . $a . "
\n"; echo "

Preincrement

"; $a = 5; echo "Should be 6: " . ++$a . "
\n"; echo "Should be 6: " . $a . "
\n"; echo "

Postdecrement

"; $a = 5; echo "Should be 5: " . $a-- . "
\n"; echo "Should be 4: " . $a . "
\n"; echo "

Predecrement

"; $a = 5; echo "Should be 4: " . --$a . "
\n"; echo "Should be 4: " . $a . "
\n"; ?> PHP follows Perl's convention when dealing with arithmetic operations on character variables and not C's. For example, in PHP and Perl $a = 'Z'; $a++; turns $a into 'AA', while in C a = 'Z'; a++; turns a into '[' (ASCII value of 'Z' is 90, ASCII value of '[' is 91). Note that character variables can be incremented but not decremented and even so only plain ASCII characters (a-z and A-Z) are supported. Incrementing/decrementing other character variables has no effect, the original string is unchanged. Example #1 Arithmetic Operations on Character Variables The above example will output: X Y Z AA AB AC Incrementing or decrementing booleans has no effect. ---------------------------------------------------------------------- ---------------------------------------------------------------------- Logical Operators Logical Operators Example Name Result $a and $b And TRUE if both $a and $b are TRUE. $a or $b Or TRUE if either $a or $b is TRUE. $a xor $b Xor TRUE if either $a or $b is TRUE, but not both. ! $a Not TRUE if $a is not TRUE. $a && $b And TRUE if both $a and $b are TRUE. $a || $b Or TRUE if either $a or $b is TRUE. The reason for the two different variations of "and" and "or" operators is that they operate at different precedences. (See Operator Precedence.) Example #1 Logical operators illustrated The above example will output something similar to: bool(true) bool(false) bool(false) bool(true) ---------------------------------------------------------------------- ---------------------------------------------------------------------- String Operators There are two string operators. The first is the concatenation operator ('.'), which returns the concatenation of its right and left arguments. The second is the concatenating assignment operator ('.='), which appends the argument on the right side to the argument on the left side. Please read Assignment Operators for more information. See also the manual sections on the String type and String functions. ---------------------------------------------------------------------- ---------------------------------------------------------------------- Array Operators Array Operators Example Name Result $a + $b Union Union of $a and $b. $a == $b Equality TRUE if $a and $b have the same key/value pairs. $a === $b Identity TRUE if $a and $b have the same key/value pairs in the same order and of the same types. $a != $b Inequality TRUE if $a is not equal to $b. $a <> $b Inequality TRUE if $a is not equal to $b. $a !== $b Non-identity TRUE if $a is not identical to $b. The + operator returns the right-hand array appended to the left-hand array; for keys that exist in both arrays, the elements from the left-hand array will be used, and the matching elements from the right-hand array will be ignored. "apple", "b" => "banana"); $b = array("a" => "pear", "b" => "strawberry", "c" => "cherry"); $c = $a + $b; // Union of $a and $b echo "Union of \$a and \$b: \n"; var_dump($c); $c = $b + $a; // Union of $b and $a echo "Union of \$b and \$a: \n"; var_dump($c); ?> When executed, this script will print the following: Union of $a and $b: array(3) { ["a"]=> string(5) "apple" ["b"]=> string(6) "banana" ["c"]=> string(6) "cherry" } Union of $b and $a: array(3) { ["a"]=> string(4) "pear" ["b"]=> string(10) "strawberry" ["c"]=> string(6) "cherry" } Elements of arrays are equal for the comparison if they have the same key and value. Example #1 Comparing arrays "banana", "0" => "apple"); var_dump($a == $b); // bool(true) var_dump($a === $b); // bool(false) ?> See also the manual sections on the Array type and Array functions. ---------------------------------------------------------------------- ---------------------------------------------------------------------- Type Operators instanceof is used to determine whether a PHP variable is an instantiated object of a certain class: Example #1 Using instanceof with classes The above example will output: bool(true) bool(false) instanceof can also be used to determine whether a variable is an instantiated object of a class that inherits from a parent class: Example #2 Using instanceof with inherited classes The above example will output: bool(true) bool(true) To check if an object is not an instanceof a class, the logical not operator can be used. Example #3 Using instanceof to check if object is not an instanceof a class The above example will output: bool(true) Lastly, instanceof can also be used to determine whether a variable is an instantiated object of a class that implements an interface: Example #4 Using instanceof for class The above example will output: bool(true) bool(true) Although instanceof is usually used with a literal classname, it can also be used with another object or a string variable: Example #5 Using instanceof with other variables The above example will output: bool(true) bool(true) bool(false) There are a few pitfalls to be aware of. Before PHP version 5.1.0, instanceof would call __autoload() if the class name did not exist. In addition, if the class was not loaded, a fatal error would occur. This can be worked around by using a dynamic class reference, or a string variable containing the class name: Example #6 Avoiding classname lookups and fatal errors with instanceof in PHP 5.0 The above example will output: bool(false) The instanceof operator was introduced in PHP 5. Before this time is_a() was used but is_a() has since been deprecated in favor of instanceof. Note that as of PHP 5.3.0, is_a() is no longer deprecated. See also get_class() and is_a(). ---------------------------------------------------------------------- ---------------------------------------------------------------------- ---------------------------------------------------------------------- Control Structures Table of Contents * Introduction * if * else * elseif/else if * Alternative syntax for control structures * while * do-while * for * foreach * break * continue * switch * declare * return * require * include * require_once * include_once * goto ---------------------------------------------------------------------- Introduction Any PHP script is built out of a series of statements. A statement can be an assignment, a function call, a loop, a conditional statement or even a statement that does nothing (an empty statement). Statements usually end with a semicolon. In addition, statements can be grouped into a statement-group by encapsulating a group of statements with curly braces. A statement-group is a statement by itself as well. The various statement types are described in this chapter. ---------------------------------------------------------------------- ---------------------------------------------------------------------- if The if construct is one of the most important features of many languages, PHP included. It allows for conditional execution of code fragments. PHP features an if structure that is similar to that of C: if (expr) statement As described in the section about expressions, expression is evaluated to its Boolean value. If expression evaluates to TRUE, PHP will execute statement, and if it evaluates to FALSE - it'll ignore it. More information about what values evaluate to FALSE can be found in the 'Converting to boolean' section. The following example would display a is bigger than b if $a is bigger than $b: $b) echo "a is bigger than b"; ?> Often you'd want to have more than one statement to be executed conditionally. Of course, there's no need to wrap each statement with an if clause. Instead, you can group several statements into a statement group. For example, this code would display a is bigger than b if $a is bigger than $b, and would then assign the value of $a into $b: $b) { echo "a is bigger than b"; $b = $a; } ?> If statements can be nested infinitely within other if statements, which provides you with complete flexibility for conditional execution of the various parts of your program. ---------------------------------------------------------------------- ---------------------------------------------------------------------- else Often you'd want to execute a statement if a certain condition is met, and a different statement if the condition is not met. This is what else is for. else extends an if statement to execute a statement in case the expression in the if statement evaluates to FALSE. For example, the following code would display a is greater than b if $a is greater than $b, and a is NOT greater than b otherwise: $b) { echo "a is greater than b"; } else { echo "a is NOT greater than b"; } ?> The else statement is only executed if the if expression evaluated to FALSE, and if there were any elseif expressions - only if they evaluated to FALSE as well (see elseif). ---------------------------------------------------------------------- ---------------------------------------------------------------------- elseif/else if elseif, as its name suggests, is a combination of if and else. Like else, it extends an if statement to execute a different statement in case the original if expression evaluates to FALSE. However, unlike else, it will execute that alternative expression only if the elseif conditional expression evaluates to TRUE. For example, the following code would display a is bigger than b, a equal to b or a is smaller than b: $b) { echo "a is bigger than b"; } elseif ($a == $b) { echo "a is equal to b"; } else { echo "a is smaller than b"; } ?> There may be several elseifs within the same if statement. The first elseif expression (if any) that evaluates to TRUE would be executed. In PHP, you can also write 'else if' (in two words) and the behavior would be identical to the one of 'elseif' (in a single word). The syntactic meaning is slightly different (if you're familiar with C, this is the same behavior) but the bottom line is that both would result in exactly the same behavior. The elseif statement is only executed if the preceding if expression and any preceding elseif expressions evaluated to FALSE, and the current elseif expression evaluated to TRUE. Note: Note that elseif and else if will only be considered exactly the same when using curly brackets as in the above example. When using a colon to define your if/elseif conditions, you must not separate else if into two words, or PHP will fail with a parse error. $b): echo $a." is greater than ".$b; else if($a == $b): // Will not compile. echo "The above line causes a parse error."; endif; /* Correct Method: */ if($a > $b): echo $a." is greater than ".$b; elseif($a == $b): // Note the combination of the words. echo $a." equals ".$b; else: echo $a." is neither greater than or equal to ".$b; endif; ?> ---------------------------------------------------------------------- ---------------------------------------------------------------------- Alternative syntax for control structures PHP offers an alternative syntax for some of its control structures; namely, if, while, for, foreach, and switch. In each case, the basic form of the alternate syntax is to change the opening brace to a colon (:) and the closing brace to endif;, endwhile;, endfor;, endforeach;, or endswitch;, respectively. A is equal to 5 In the above example, the HTML block "A is equal to 5" is nested within an if statement written in the alternative syntax. The HTML block would be displayed only if $a is equal to 5. The alternative syntax applies to else and elseif as well. The following is an if structure with elseif and else in the alternative format: Note: Mixing syntaxes in the same control block is not supported. See also while, for, and if for further examples. ---------------------------------------------------------------------- ---------------------------------------------------------------------- while while loops are the simplest type of loop in PHP. They behave just like their C counterparts. The basic form of a while statement is: while (expr) statement The meaning of a while statement is simple. It tells PHP to execute the nested statement(s) repeatedly, as long as the while expression evaluates to TRUE. The value of the expression is checked each time at the beginning of the loop, so even if this value changes during the execution of the nested statement(s), execution will not stop until the end of the iteration (each time PHP runs the statements in the loop is one iteration). Sometimes, if the while expression evaluates to FALSE from the very beginning, the nested statement(s) won't even be run once. Like with the if statement, you can group multiple statements within the same while loop by surrounding a group of statements with curly braces, or by using the alternate syntax: while (expr): statement ... endwhile; The following examples are identical, and both print the numbers 1 through 10: ---------------------------------------------------------------------- ---------------------------------------------------------------------- do-while do-while loops are very similar to while loops, except the truth expression is checked at the end of each iteration instead of in the beginning. The main difference from regular while loops is that the first iteration of a do-while loop is guaranteed to run (the truth expression is only checked at the end of the iteration), whereas it may not necessarily run with a regular while loop (the truth expression is checked at the beginning of each iteration, if it evaluates to FALSE right from the beginning, the loop execution would end immediately). There is just one syntax for do-while loops: 0); ?> The above loop would run one time exactly, since after the first iteration, when truth expression is checked, it evaluates to FALSE ($i is not bigger than 0) and the loop execution ends. Advanced C users may be familiar with a different usage of the do-while loop, to allow stopping execution in the middle of code blocks, by encapsulating them with do-while (0), and using the break statement. The following code fragment demonstrates this: Don't worry if you don't understand this right away or at all. You can code scripts and even powerful scripts without using this 'feature'. Since PHP 5.3.0, it is possible to use goto operator instead of this hack. ---------------------------------------------------------------------- ---------------------------------------------------------------------- for for loops are the most complex loops in PHP. They behave like their C counterparts. The syntax of a for loop is: for (expr1; expr2; expr3) statement The first expression (expr1) is evaluated (executed) once unconditionally at the beginning of the loop. In the beginning of each iteration, expr2 is evaluated. If it evaluates to TRUE, the loop continues and the nested statement(s) are executed. If it evaluates to FALSE, the execution of the loop ends. At the end of each iteration, expr3 is evaluated (executed). Each of the expressions can be empty or contain multiple expressions separated by commas. In expr2, all expressions separated by a comma are evaluated but the result is taken from the last part. expr2 being empty means the loop should be run indefinitely (PHP implicitly considers it as TRUE, like C). This may not be as useless as you might think, since often you'd want to end the loop using a conditional break statement instead of using the for truth expression. Consider the following examples. All of them display the numbers 1 through 10: 10) { break; } echo $i; } /* example 3 */ $i = 1; for (; ; ) { if ($i > 10) { break; } echo $i; $i++; } /* example 4 */ for ($i = 1, $j = 0; $i <= 10; $j += $i, print $i, $i++); ?> Of course, the first example appears to be the nicest one (or perhaps the fourth), but you may find that being able to use empty expressions in for loops comes in handy in many occasions. PHP also supports the alternate "colon syntax" for for loops. for (expr1; expr2; expr3): statement ... endfor; Its a common thing to many users to iterate though arrays like in the example below. 'Kalle', 'salt' => 856412), Array('name' => 'Pierre', 'salt' => 215863) ); for($i = 0; $i < sizeof($people); ++$i) { $people[$i]['salt'] = rand(000000, 999999); } ?> The problem lies in the second for expression. This code can be slow because it has to calculate the size of the array on each iteration. Since the size never change, it can be optimized easily using an intermediate variable to store the size and use in the loop instead of sizeof. The example below illustrates this: 'Kalle', 'salt' => 856412), Array('name' => 'Pierre', 'salt' => 215863) ); for($i = 0, $size = sizeof($people); $i < $size; ++$i) { $people[$i]['salt'] = rand(000000, 999999); } ?> ---------------------------------------------------------------------- ---------------------------------------------------------------------- foreach PHP 4 introduced a foreach construct, much like Perl and some other languages. This simply gives an easy way to iterate over arrays. foreach works only on arrays, and will issue an error when you try to use it on a variable with a different data type or an uninitialized variable. There are two syntaxes; the second is a minor but useful extension of the first: foreach (array_expression as $value) statement foreach (array_expression as $key => $value) statement The first form loops over the array given by array_expression. On each loop, the value of the current element is assigned to $value and the internal array pointer is advanced by one (so on the next loop, you'll be looking at the next element). The second form does the same thing, except that the current element's key will be assigned to the variable $key on each loop. As of PHP 5, it is possible to iterate objects too. Note: When foreach first starts executing, the internal array pointer is automatically reset to the first element of the array. This means that you do not need to call reset() before a foreach loop. Note: Unless the array is referenced, foreach operates on a copy of the specified array and not the array itself. foreach has some side effects on the array pointer. Don't rely on the array pointer during or after the foreach without resetting it. As of PHP 5, you can easily modify array's elements by preceding $value with &. This will assign reference instead of copying the value. This is possible only if iterated array can be referenced (i.e. is variable), that means the following code won't work: Warning Reference of a $value and the last array element remain even after the foreach loop. It is recommended to destroy it by unset(). Note: foreach does not support the ability to suppress error messages using '@'. You may have noticed that the following are functionally identical: \n"; } foreach ($arr as $value) { echo "Value: $value
\n"; } ?> The following are also functionally identical: \n"; } foreach ($arr as $key => $value) { echo "Key: $key; Value: $value
\n"; } ?> Some more examples to demonstrate usages: $v.\n"; $i++; } /* foreach example 3: key and value */ $a = array( "one" => 1, "two" => 2, "three" => 3, "seventeen" => 17 ); foreach ($a as $k => $v) { echo "\$a[$k] => $v.\n"; } /* foreach example 4: multi-dimensional arrays */ $a = array(); $a[0][0] = "a"; $a[0][1] = "b"; $a[1][0] = "y"; $a[1][1] = "z"; foreach ($a as $v1) { foreach ($v1 as $v2) { echo "$v2\n"; } } /* foreach example 5: dynamic arrays */ foreach (array(1, 2, 3, 4, 5) as $v) { echo "$v\n"; } ?> ---------------------------------------------------------------------- ---------------------------------------------------------------------- break break ends execution of the current for, foreach, while, do-while or switch structure. break accepts an optional numeric argument which tells it how many nested enclosing structures are to be broken out of. \n"; } /* Using the optional argument. */ $i = 0; while (++$i) { switch ($i) { case 5: echo "At 5
\n"; break 1; /* Exit only the switch. */ case 10: echo "At 10; quitting
\n"; break 2; /* Exit the switch and the while. */ default: break; } } ?> ---------------------------------------------------------------------- ---------------------------------------------------------------------- continue continue is used within looping structures to skip the rest of the current loop iteration and continue execution at the condition evaluation and then the beginning of the next iteration. Note: Note that in PHP the switch statement is considered a looping structure for the purposes of continue. continue accepts an optional numeric argument which tells it how many levels of enclosing loops it should skip to the end of. Note: continue 0; and continue 1; is the same as running continue;. \n"; while (1) { echo " Middle
\n"; while (1) { echo "  Inner
\n"; continue 3; } echo "This never gets output.
\n"; } echo "Neither does this.
\n"; } ?> Omitting the semicolon after continue can lead to confusion. Here's an example of what you shouldn't do. One can expect the result to be: 0 1 3 4 but this script will output: 2 because the entire continue print "$i\n"; is evaluated as a single expression, and so print() is called only when $i == 2 is true. (The return value of print is passed to continue as the numeric argument.) ---------------------------------------------------------------------- ---------------------------------------------------------------------- switch The switch statement is similar to a series of IF statements on the same expression. In many occasions, you may want to compare the same variable (or expression) with many different values, and execute a different piece of code depending on which value it equals to. This is exactly what the switch statement is for. Note: Note that unlike some other languages, the continue statement applies to switch and acts similar to break. If you have a switch inside a loop and wish to continue to the next iteration of the outer loop, use continue 2. Note: Note that switch/case does loose comparision. The following two examples are two different ways to write the same thing, one using a series of if and elseif statements, and the other using the switch statement: Example #1 switch structure Example #2 switch structure allows usage of strings It is important to understand how the switch statement is executed in order to avoid mistakes. The switch statement executes line by line (actually, statement by statement). In the beginning, no code is executed. Only when a case statement is found with a value that matches the value of the switch expression does PHP begin to execute the statements. PHP continues to execute the statements until the end of the switch block, or the first time it sees a break statement. If you don't write a break statement at the end of a case's statement list, PHP will go on executing the statements of the following case. For example: Here, if $i is equal to 0, PHP would execute all of the echo statements! If $i is equal to 1, PHP would execute the last two echo statements. You would get the expected behavior ('i equals 2' would be displayed) only if $i is equal to 2. Thus, it is important not to forget break statements (even though you may want to avoid supplying them on purpose under certain circumstances). In a switch statement, the condition is evaluated only once and the result is compared to each case statement. In an elseif statement, the condition is evaluated again. If your condition is more complicated than a simple compare and/or is in a tight loop, a switch may be faster. The statement list for a case can also be empty, which simply passes control into the statement list for the next case. A special case is the default case. This case matches anything that wasn't matched by the other cases. For example: The case expression may be any expression that evaluates to a simple type, that is, integer or floating-point numbers and strings. Arrays or objects cannot be used here unless they are dereferenced to a simple type. The alternative syntax for control structures is supported with switches. For more information, see Alternative syntax for control structures. Its possible to use a semicolon instead of a colon after a case like: ---------------------------------------------------------------------- ---------------------------------------------------------------------- declare The declare construct is used to set execution directives for a block of code. The syntax of declare is similar to the syntax of other flow control constructs: declare (directive) statement The directive section allows the behavior of the declare block to be set. Currently only two directives are recognized: the ticks directive (See below for more information on the ticks directive) and the encoding directive (See below for more information on the encoding directive). Note: The encoding directive was added in PHP 5.3.0 The statement part of the declare block will be executed - how it is executed and what side effects occur during execution may depend on the directive set in the directive block. The declare construct can also be used in the global scope, affecting all code following it (however if the file with declare was included then it does not affect the parent file). Ticks A tick is an event that occurs for every N low-level tickable statements executed by the parser within the declare block. The value for N is specified using ticks=N within the declare blocks's directive section. Not all statements are tickable. Typically, condition expressions and argument expressions are not tickable. The event(s) that occur on each tick are specified using the register_tick_function(). See the example below for more details. Note that more than one event can occur for each tick. Example #1 Tick usage example 0) { $a += 2; print($a); } ?> Example #2 Ticks usage example 0) { $a += 2; tick_handler(); print($a); tick_handler(); } tick_handler(); ?> See also register_tick_function() and unregister_tick_function(). Encoding A script's encoding can be specified per-script using the encoding directive. Example #3 Declaring an encoding for the script. Caution When combined with namespaces, the only legal syntax for declare is declare(encoding='...'); where ... is the encoding value. declare(encoding='...') {} will result in a parse error when combined with namespaces. The encoding declare value is ignored in PHP 5.3 unless php is compiled with --enable-zend-multibyte. Note that PHP does not expose whether --enable-zend-multibyte was used to compile PHP other than by phpinfo(). ---------------------------------------------------------------------- ---------------------------------------------------------------------- return If called from within a function, the return() statement immediately ends execution of the current function, and returns its argument as the value of the function call. return() will also end the execution of an eval() statement or script file. If called from the global scope, then execution of the current script file is ended. If the current script file was include()ed or require()ed, then control is passed back to the calling file. Furthermore, if the current script file was include()ed, then the value given to return() will be returned as the value of the include() call. If return() is called from within the main script file, then script execution ends. If the current script file was named by the auto_prepend_file or auto_append_file configuration options in php.ini, then that script file's execution is ended. For more information, see Returning values. Note: Note that since return() is a language construct and not a function, the parentheses surrounding its arguments are not required. It is common to leave them out, and you actually should do so as PHP has less work to do in this case. Note: If no parameter is supplied, then the parentheses must be omitted and NULL will be returned. Calling return() with parentheses but with no arguments will result in a parse error. Note: You should never use parentheses around your return variable when returning by reference, as this will not work. You can only return variables by reference, not the result of a statement. If you use return ($a); then you're not returning a variable, but the result of the expression ($a) (which is, of course, the value of $a). ---------------------------------------------------------------------- ---------------------------------------------------------------------- require() require() is identical to include() except upon failure it will also produce a fatal E_COMPILE_ERROR level error. In other words, it will halt the script whereas include() only emits a warning (E_WARNING) which allows the script to continue. See the include() documentation for how this works. ---------------------------------------------------------------------- ---------------------------------------------------------------------- include() The include() statement includes and evaluates the specified file. The documentation below also applies to require(). Files are included based on the file path given or, if none is given, the include_path specified. If the file isn't found in the include_path, include() will finally check in the calling script's own directory and the current working directory before failing. The include() construct will emit a warning if it cannot find a file; this is different behavior from require(), which will emit a fatal error. If a path is defined - whether absolute (starting with a drive letter or \ on Windows, or / on Unix/Linux systems) or relative to the current directory (starting with . or ..) - the include_path will be ignored altogether. For example, if a filename begins with ../, the parser will look in the parent directory to find the requested file. For more information on how PHP handles including files and the include path, see the documentation for include_path. When a file is included, the code it contains inherits the variable scope of the line on which the include occurs. Any variables available at that line in the calling file will be available within the called file, from that point forward. However, all functions and classes defined in the included file have the global scope. Example #1 Basic include() example vars.php test.php If the include occurs inside a function within the calling file, then all of the code contained in the called file will behave as though it had been defined inside that function. So, it will follow the variable scope of that function. An exception to this rule are magic constants which are evaluated by the parser before the include occurs. Example #2 Including within functions When a file is included, parsing drops out of PHP mode and into HTML mode at the beginning of the target file, and resumes again at the end. For this reason, any code inside the target file which should be executed as PHP code must be enclosed within valid PHP start and end tags. If "URL fopen wrappers" are enabled in PHP (which they are in the default configuration), you can specify the file to be included using a URL (via HTTP or other supported wrapper - see Supported Protocols and Wrappers for a list of protocols) instead of a local pathname. If the target server interprets the target file as PHP code, variables may be passed to the included file using a URL request string as used with HTTP GET. This is not strictly speaking the same thing as including the file and having it inherit the parent file's variable scope; the script is actually being run on the remote server and the result is then being included into the local script. Warning Windows versions of PHP prior to PHP 4.3.0 do not support access of remote files via this function, even if allow_url_fopen is enabled. Example #3 include() through HTTP Warning Security warning Remote file may be processed at the remote server (depending on the file extension and the fact if the remote server runs PHP or not) but it still has to produce a valid PHP script because it will be processed at the local server. If the file from the remote server should be processed there and outputted only, readfile() is much better function to use. Otherwise, special care should be taken to secure the remote script to produce a valid and desired code. See also Remote files, fopen() and file() for related information. Handling Returns: It is possible to execute a return() statement inside an included file in order to terminate processing in that file and return to the script which called it. Also, it's possible to return values from included files. You can take the value of the include call as you would a normal function. This is not, however, possible when including remote files unless the output of the remote file has valid PHP start and end tags (as with any local file). You can declare the needed variables within those tags and they will be introduced at whichever point the file was included. Because include() is a special language construct, parentheses are not needed around its argument. Take care when comparing return value. Example #4 Comparing return value of include Example #5 include() and the return() statement return.php noreturn.php testreturns.php $bar is the value 1 because the include was successful. Notice the difference between the above examples. The first uses return() within the included file while the other does not. If the file can't be included, FALSE is returned and E_WARNING is issued. If there are functions defined in the included file, they can be used in the main file independent if they are before return() or after. If the file is included twice, PHP 5 issues fatal error because functions were already declared, while PHP 4 doesn't complain about functions defined after return(). It is recommended to use include_once() instead of checking if the file was already included and conditionally return inside the included file. Another way to "include" a PHP file into a variable is to capture the output by using the Output Control Functions with include(). For example: Example #6 Using output buffering to include a PHP file into a string In order to automatically include files within scripts, see also the auto_prepend_file and auto_append_file configuration options in php.ini. Note: Because this is a language construct and not a function, it cannot be called using variable functions See also require(), require_once(), include_once(), get_included_files(), readfile(), virtual(), and include_path. ---------------------------------------------------------------------- ---------------------------------------------------------------------- require_once() The require_once() statement is identical to require() except PHP will check if the file has already been included, and if so, not include (require) it again. See the include_once() documentation for information about the _once behaviour, and how it differs from its non _once siblings. ---------------------------------------------------------------------- ---------------------------------------------------------------------- include_once() The include_once() statement includes and evaluates the specified file during the execution of the script. This is a behavior similar to the include() statement, with the only difference being that if the code from a file has already been included, it will not be included again. As the name suggests, it will be included just once. include_once() may be used in cases where the same file might be included and evaluated more than once during a particular execution of a script, so in this case it may help avoid problems such as function redefinitions, variable value reassignments, etc. See the include() documentation for information about how this function works. Note: With PHP 4, _once functionality differs with case-insensitive operating systems (like Windows) so for example: Example #1 include_once() with a case insensitive OS in PHP 4 This behaviour changed in PHP 5, so for example with Windows the path is normalized first so that C:\PROGRA~1\A.php is realized the same as C:\Program Files\a.php and the file is included just once. ---------------------------------------------------------------------- ---------------------------------------------------------------------- goto The goto operator can be used to jump to another section in the program. The target point is specified by a label followed by a colon, and the instruction is given as goto followed by the desired target label. This is not a full unrestricted goto. The target label must be within the same file and context, meaning that you cannot jump out of a function or method, nor can you jump into one. You also cannot jump into any sort of loop or switch structure. You may jump out of these, and a common use is to use a goto in place of a multi-level break. Example #1 goto example The above example will output: Bar Example #2 goto loop example The above example will output: j hit 17 Example #3 This will not work The above example will output: Fatal error: 'goto' into loop or switch statement is disallowed in script on line 2 Note: The goto operator is available as of PHP 5.3. What's the worse thing that could happen if you use goto? Image courtesy of >> xkcd ---------------------------------------------------------------------- ---------------------------------------------------------------------- ---------------------------------------------------------------------- Functions Table of Contents * User-defined functions * Function arguments * Returning values * Variable functions * Internal (built-in) functions * Anonymous functions ---------------------------------------------------------------------- User-defined functions A function may be defined using syntax such as the following: Example #1 Pseudo code to demonstrate function uses Any valid PHP code may appear inside a function, even other functions and class definitions. Function names follow the same rules as other labels in PHP. A valid function name starts with a letter or underscore, followed by any number of letters, numbers, or underscores. As a regular expression, it would be expressed thus: [a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*. Tip See also the Userland Naming Guide. Functions need not be defined before they are referenced, except when a function is conditionally defined as shown in the two examples below. When a function is defined in a conditional manner such as the two examples shown. Its definition must be processed prior to being called. Example #2 Conditional functions Example #3 Functions within functions All functions and classes in PHP have the global scope - they can be called outside a function even if they were defined inside and vice versa. PHP does not support function overloading, nor is it possible to undefine or redefine previously-declared functions. Note: Function names are case-insensitive, though it is usually good form to call functions as they appear in their declaration. Both variable number of arguments and default arguments are supported in functions. See also the function references for func_num_args(), func_get_arg(), and func_get_args() for more information. It is possible to call recursive functions in PHP. However avoid recursive function/method calls with over 100-200 recursion levels as it can smash the stack and cause a termination of the current script. Example #4 Recursive functions ---------------------------------------------------------------------- ---------------------------------------------------------------------- Function arguments Information may be passed to functions via the argument list, which is a comma-delimited list of expressions. PHP supports passing arguments by value (the default), passing by reference, and default argument values. Variable-length argument lists are also supported, see also the function references for func_num_args(), func_get_arg(), and func_get_args() for more information. Example #1 Passing arrays to functions Making arguments be passed by reference By default, function arguments are passed by value (so that if the value of the argument within the function is changed, it does not get changed outside of the function). To allow a function to modify its arguments, they must be passed by reference. To have an argument to a function always passed by reference, prepend an ampersand (&) to the argument name in the function definition: Example #2 Passing function parameters by reference Default argument values A function may define C++-style default values for scalar arguments as follows: Example #3 Use of default parameters in functions The above example will output: Making a cup of cappuccino. Making a cup of . Making a cup of espresso. PHP also allows the use of arrays and the special type NULL as default values, for example: Example #4 Using non-scalar types as default values The default value must be a constant expression, not (for example) a variable, a class member or a function call. Note that when using default arguments, any defaults should be on the right side of any non-default arguments; otherwise, things will not work as expected. Consider the following code snippet: Example #5 Incorrect usage of default function arguments The above example will output: Warning: Missing argument 2 in call to makeyogurt() in /usr/local/etc/httpd/htdocs/phptest/functest.html on line 41 Making a bowl of raspberry . Now, compare the above with this: Example #6 Correct usage of default function arguments The above example will output: Making a bowl of acidophilus raspberry. Note: As of PHP 5, default values may be passed by reference. Variable-length argument lists PHP 4 and above has support for variable-length argument lists in user-defined functions. This is really quite easy, using the func_num_args(), func_get_arg(), and func_get_args() functions. No special syntax is required, and argument lists may still be explicitly provided with function definitions and will behave as normal. ---------------------------------------------------------------------- ---------------------------------------------------------------------- Returning values Values are returned by using the optional return statement. Any type may be returned, including arrays and objects. This causes the function to end its execution immediately and pass control back to the line from which it was called. See return() for more information. Note: If the return() is omitted the value NULL will be returned. Example #1 Use of return() A function can not return multiple values, but similar results can be obtained by returning an array. Example #2 Returning an array to get multiple values To return a reference from a function, use the reference operator & in both the function declaration and when assigning the returned value to a variable: Example #3 Returning a reference from a function For more information on references, please check out References Explained. ---------------------------------------------------------------------- ---------------------------------------------------------------------- Variable functions PHP supports the concept of variable functions. This means that if a variable name has parentheses appended to it, PHP will look for a function with the same name as whatever the variable evaluates to, and will attempt to execute it. Among other things, this can be used to implement callbacks, function tables, and so forth. Variable functions won't work with language constructs such as echo(), print(), unset(), isset(), empty(), include(), require() and the like. Utilize wrapper functions to make use of any of these constructs as variable functions. Example #1 Variable function example \n"; } function bar($arg = '') { echo "In bar(); argument was '$arg'.
\n"; } // This is a wrapper function around echo function echoit($string) { echo $string; } $func = 'foo'; $func(); // This calls foo() $func = 'bar'; $func('test'); // This calls bar() $func = 'echoit'; $func('test'); // This calls echoit() ?> An object method can also be called with the variable functions syntax. Example #2 Variable method example $name(); // This calls the Bar() method } function Bar() { echo "This is Bar"; } } $foo = new Foo(); $funcname = "Variable"; $foo->$funcname(); // This calls $foo->Variable() ?> When calling static methods, the function call is stronger than the static property operator: Example #3 Variable method example with static properties Variable() reading $variable in this scope. ?> See also call_user_func(), variable variables and function_exists(). ---------------------------------------------------------------------- ---------------------------------------------------------------------- Internal (built-in) functions PHP comes standard with many functions and constructs. There are also functions that require specific PHP extensions compiled in, otherwise fatal "undefined function" errors will appear. For example, to use image functions such as imagecreatetruecolor(), PHP must be compiled with GD support. Or, to use mysql_connect(), PHP must be compiled with MySQL support. There are many core functions that are included in every version of PHP, such as the string and variable functions. A call to phpinfo() or get_loaded_extensions() will show which extensions are loaded into PHP. Also note that many extensions are enabled by default and that the PHP manual is split up by extension. See the configuration, installation, and individual extension chapters, for information on how to set up PHP. Reading and understanding a function's prototype is explained within the manual section titled how to read a function definition. It's important to realize what a function returns or if a function works directly on a passed in value. For example, str_replace() will return the modified string while usort() works on the actual passed in variable itself. Each manual page also has specific information for each function like information on function parameters, behavior changes, return values for both success and failure, and availability information. Knowing these important (yet often subtle) differences is crucial for writing correct PHP code. Note: If the parameters given to a function are not what it expects, such as passing an array where a string is expected, the return value of the function is undefined. In this case it will likely return NULL but this is just a convention, and cannot be relied upon. See also function_exists(), the function reference, get_extension_funcs(), and dl(). ---------------------------------------------------------------------- ---------------------------------------------------------------------- Anonymous functions Anonymous functions, also known as closures, allow the creation of functions which have no specified name. They are most useful as the value of callback parameters, but they have many other uses. Example #1 Anonymous function example Closures can also be used as the values of variables; PHP automatically converts such expressions into instances of the Closure internal class. Assigning a closure to a variable uses the same syntax as any other assignment, including the trailing semicolon: Example #2 Anonymous function variable assignment example Closures may also inherit variables from the parent scope. Any such variables must be declared in the function header. Inheriting variables from the parent scope is not the same as using global variables. Global variables exist in the global scope, which is the same no matter what function is executing. The parent scope of a closure is the function in which the closure was declared (not necessarily the function it was called from). See the following example: Example #3 Closures and scoping products[$product] = $quantity; } public function getQuantity($product) { return isset($this->products[$product]) ? $this->products[$product] : FALSE; } public function getTotal($tax) { $total = 0.00; $callback = function ($quantity, $product) use ($tax, &$total) { $pricePerItem = constant(__CLASS__ . "::PRICE_" . strtoupper($product)); $total += ($pricePerItem * $quantity) * ($tax + 1.0); }; array_walk($this->products, $callback); return round($total, 2); } } $my_cart = new Cart; // Add some items to the cart $my_cart->add('butter', 1); $my_cart->add('milk', 3); $my_cart->add('eggs', 6); // Print the total with a 5% sales tax. print $my_cart->getTotal(0.05) . "\n"; // The result is 54.29 ?> Anonymous functions are currently implemented using the Closure class. This is an implementation detail and should not be relied upon. Note: Anonymous functions are available since PHP 5.3.0. Note: It was not possible to use $this from anonymous function before PHP 5.4.0. Note: It is possible to use func_num_args(), func_get_arg(), and func_get_args() from within a closure. ---------------------------------------------------------------------- ---------------------------------------------------------------------- ---------------------------------------------------------------------- Classes and Objects Table of Contents * Introduction * The Basics * Properties * Class Constants * Autoloading Classes * Constructors and Destructors * Visibility * Object Inheritance * Scope Resolution Operator (::) * Static Keyword * Class Abstraction * Object Interfaces * Overloading * Object Iteration * Patterns * Magic Methods * Final Keyword * Object Cloning * Comparing Objects * Type Hinting * Late Static Bindings * Objects and references * Object Serialization * OOP Changelog ---------------------------------------------------------------------- Introduction Starting with PHP 5, the object model was rewritten to allow for better performance and more features. This was a major change from PHP 4. PHP 5 has a full object model. Among the features in PHP 5 are the inclusions of visibility, abstract and final classes and methods, additional magic methods, interfaces, cloning and typehinting. PHP treats objects in the same way as references or handles, meaning that each variable contains an object reference rather than a copy of the entire object. See Objects and References Tip See also the Userland Naming Guide. ---------------------------------------------------------------------- ---------------------------------------------------------------------- The Basics class Basic class definitions begin with the keyword class, followed by a class name, followed by a pair of curly braces which enclose the definitions of the properties and methods belonging to the class. The class name can be any valid label which is a not a PHP reserved word. A valid class name starts with a letter or underscore, followed by any number of letters, numbers, or underscores. As a regular expression, it would be expressed thus: [a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*. A class may contain its own constants, variables (called "properties"), and functions (called "methods"). Example #1 Simple Class definition var; } } ?> The pseudo-variable $this is available when a method is called from within an object context. $this is a reference to the calling object (usually the object to which the method belongs, but possibly another object, if the method is called statically from the context of a secondary object). Example #2 Some examples of the $this pseudo-variable foo(); // Note: the next line will issue a warning if E_STRICT is enabled. A::foo(); $b = new B(); $b->bar(); // Note: the next line will issue a warning if E_STRICT is enabled. B::bar(); ?> The above example will output: $this is defined (A) $this is not defined. $this is defined (B) $this is not defined. new To create an instance of a class, the new keyword must be used. An object will always be created unless the object has a constructor defined that throws an exception on error. Classes should be defined before instantiation (and in some cases this is a requirement). If a string containing the name of a class is used with new, a new instance of that class will be created. If the class is in a namespace, its fully qualified name must be used when doing this. Example #3 Creating an instance In the class context, it is possible to create a new object by new self and new parent. When assigning an already created instance of a class to a new variable, the new variable will access the same instance as the object that was assigned. This behaviour is the same when passing instances to a function. A copy of an already created object can be made by cloning it. Example #4 Object Assignment var = '$assigned will have this value'; $instance = null; // $instance and $reference become null var_dump($instance); var_dump($reference); var_dump($assigned); ?> The above example will output: NULL NULL object(SimpleClass)#1 (1) { ["var"]=> string(30) "$assigned will have this value" } PHP 5.3.0 introduced a couple of new ways to create instances of an object: Example #5 Creating new objects The above example will output: bool(true) bool(true) bool(true) extends A class can inherit the methods and properties of another class by using the keyword extends in the class declaration. It is not possible to extend multiple classes; a class can only inherit from one base class. The inherited methods and properties can be overridden by redeclaring them with the same name defined in the parent class. However, if the parent class has defined a method as final, that method may not be overridden. It is possible to access the overridden methods or static properties by referencing them with parent::. When overriding methods, the parameter signature should remain the same or PHP will generate an E_STRICT level error. This does not apply to the constructor, which allows overriding with different parameters. Example #6 Simple Class Inheritance displayVar(); ?> The above example will output: Extending class a default value ---------------------------------------------------------------------- ---------------------------------------------------------------------- Properties Class member variables are called "properties". You may also see them referred to using other terms such as "attributes" or "fields", but for the purposes of this reference we will use "properties". They are defined by using one of the keywords public, protected, or private, followed by a normal variable declaration. This declaration may include an initialization, but this initialization must be a constant value--that is, it must be able to be evaluated at compile time and must not depend on run-time information in order to be evaluated. See Visibility for more information on the meanings of public, protected, and private. Note: In order to maintain backward compatibility with PHP 4, PHP 5 will still accept the use of the keyword var in property declarations instead of (or in addition to) public, protected, or private. However, var is no longer required. In versions of PHP from 5.0 to 5.1.3, the use of var was considered deprecated and would issue an E_STRICT warning, but since PHP 5.1.3 it is no longer deprecated and does not issue the warning. If you declare a property using var instead of one of public, protected, or private, then PHP 5 will treat the property as if it had been declared as public. Within class methods the properties, constants, and methods may be accessed by using the form $this->property (where property is the name of the property) unless the access is to a static property within the context of a static class method, in which case it is accessed using the form self::$property. See Static Keyword for more information. The pseudo-variable $this is available inside any class method when that method is called from within an object context. $this is a reference to the calling object (usually the object to which the method belongs, but possibly another object, if the method is called statically from the context of a secondary object). Example #1 property declarations Note: There are some nice functions to handle classes and objects. You might want to take a look at the Class/Object Functions. Unlike heredocs, nowdocs can be used in any static data context, including property declarations. Example #2 Example of using a nowdoc to initialize a property Note: Nowdoc support was added in PHP 5.3.0. ---------------------------------------------------------------------- ---------------------------------------------------------------------- Class Constants It is possible to define constant values on a per-class basis remaining the same and unchangeable. Constants differ from normal variables in that you don't use the $ symbol to declare or use them. The value must be a constant expression, not (for example) a variable, a property, a result of a mathematical operation, or a function call. It's also possible for interfaces to have constants. Look at the interface documentation for examples. As of PHP 5.3.0, it's possible to reference the class using a variable. The variable's value can not be a keyword (e.g. self, parent and static). Example #1 Defining and using a constant showConstant(); echo $class::constant."\n"; // As of PHP 5.3.0 ?> Example #2 Static data example Unlike heredocs, nowdocs can be used in any static data context. Note: Nowdoc support was added in PHP 5.3.0. ---------------------------------------------------------------------- ---------------------------------------------------------------------- Autoloading Classes Many developers writing object-oriented applications create one PHP source file per-class definition. One of the biggest annoyances is having to write a long list of needed includes at the beginning of each script (one for each class). In PHP 5, this is no longer necessary. You may define an __autoload function which is automatically called in case you are trying to use a class/interface which hasn't been defined yet. By calling this function the scripting engine is given a last chance to load the class before PHP fails with an error. Note: Prior to 5.3.0, exceptions thrown in the __autoload function could not be caught in the catch block and would result in a fatal error. From 5.3.0+ exceptions thrown in the __autoload function can be caught in the catch block, with 1 provision. If throwing a custom exception, then the custom exception class must be available. The __autoload function may be used recursively to autoload the custom exception class. Note: Autoloading is not available if using PHP in CLI interactive mode. Note: If the class name is used e.g. in call_user_func() then it can contain some dangerous characters such as ../. It is recommended to not use the user-input in such functions or at least verify the input in __autoload(). Example #1 Autoload example This example attempts to load the classes MyClass1 and MyClass2 from the files MyClass1.php and MyClass2.php respectively. Example #2 Autoload other example This example attempts to load the interface ITest. Example #3 Autoloading with exception handling for 5.3.0+ This example throws an exception and demonstrates the try/catch block. getMessage(), "\n"; } ?> The above example will output: Want to load NonLoadableClass. Unable to load NonLoadableClass. Example #4 Autoloading with exception handling for 5.3.0+ - Missing custom exception This example throws an exception for a non-loadable, custom exception. getMessage(), "\n"; } ?> The above example will output: Want to load NonLoadableClass. Want to load MissingException. Fatal error: Class 'MissingException' not found in testMissingException.php on line 4 See Also * unserialize() * unserialize_callback_func * spl_autoload() * spl_autoload_register() ---------------------------------------------------------------------- ---------------------------------------------------------------------- Constructors and Destructors Constructor void __construct ([ mixed $args [, $... ]] ) PHP 5 allows developers to declare constructor methods for classes. Classes which have a constructor method call this method on each newly-created object, so it is suitable for any initialization that the object may need before it is used. Note: Parent constructors are not called implicitly if the child class defines a constructor. In order to run a parent constructor, a call to parent::__construct() within the child constructor is required. Example #1 using new unified constructors For backwards compatibility, if PHP 5 cannot find a __construct() function for a given class, it will search for the old-style constructor function, by the name of the class. Effectively, it means that the only case that would have compatibility issues is if the class had a method named __construct() which was used for different semantics. Unlike with other methods, PHP will not generate an E_STRICT level error message when __construct() is overridden with different parameters than the parent __construct() method has. As of PHP 5.3.3, methods with the same name as the last element of a namespaced class name will no longer be treated as constructor. This change doesn't affect non-namespaced classes. Example #2 Constructors in namespaced classes Destructor void __destruct ( void ) PHP 5 introduces a destructor concept similar to that of other object-oriented languages, such as C++. The destructor method will be called as soon as all references to a particular object are removed or when the object is explicitly destroyed or in any order in shutdown sequence. Example #3 Destructor Example name = "MyDestructableClass"; } function __destruct() { print "Destroying " . $this->name . "\n"; } } $obj = new MyDestructableClass(); ?> Like constructors, parent destructors will not be called implicitly by the engine. In order to run a parent destructor, one would have to explicitly call parent::__destruct() in the destructor body. The destructor will be called even if script execution is stopped using exit(). Calling exit() in a destructor will prevent the remaining shutdown routines from executing. Note: Destructors called during the script shutdown have HTTP headers already sent. The working directory in the script shutdown phase can be different with some SAPIs (e.g. Apache). Note: Attempting to throw an exception from a destructor (called in the time of script termination) causes a fatal error. ---------------------------------------------------------------------- ---------------------------------------------------------------------- Visibility The visibility of a property or method can be defined by prefixing the declaration with the keywords public, protected or private. Class members declared public can be accessed everywhere. Members declared protected can be accessed only within the class itself and by inherited and parent classes. Members declared as private may only be accessed by the class that defines the member. Property Visibility Class properties must be defined as public, private, or protected. If declared using var, the property will be defined as public. Example #1 Property declaration public; echo $this->protected; echo $this->private; } } $obj = new MyClass(); echo $obj->public; // Works echo $obj->protected; // Fatal Error echo $obj->private; // Fatal Error $obj->printHello(); // Shows Public, Protected and Private /** * Define MyClass2 */ class MyClass2 extends MyClass { // We can redeclare the public and protected method, but not private protected $protected = 'Protected2'; function printHello() { echo $this->public; echo $this->protected; echo $this->private; } } $obj2 = new MyClass2(); echo $obj2->public; // Works echo $obj2->private; // Undefined echo $obj2->protected; // Fatal Error $obj2->printHello(); // Shows Public, Protected2, Undefined ?> Note: The PHP 4 method of declaring a variable with the var keyword is still supported for compatibility reasons (as a synonym for the public keyword). In PHP 5 before 5.1.3, its usage would generate an E_STRICT warning. Method Visibility Class methods may be defined as public, private, or protected. Methods declared without any explicit visibility keyword are defined as public. Example #2 Method Declaration MyPublic(); $this->MyProtected(); $this->MyPrivate(); } } $myclass = new MyClass; $myclass->MyPublic(); // Works $myclass->MyProtected(); // Fatal Error $myclass->MyPrivate(); // Fatal Error $myclass->Foo(); // Public, Protected and Private work /** * Define MyClass2 */ class MyClass2 extends MyClass { // This is public function Foo2() { $this->MyPublic(); $this->MyProtected(); $this->MyPrivate(); // Fatal Error } } $myclass2 = new MyClass2; $myclass2->MyPublic(); // Works $myclass2->Foo2(); // Public and Protected work, not Private class Bar { public function test() { $this->testPrivate(); $this->testPublic(); } public function testPublic() { echo "Bar::testPublic\n"; } private function testPrivate() { echo "Bar::testPrivate\n"; } } class Foo extends Bar { public function testPublic() { echo "Foo::testPublic\n"; } private function testPrivate() { echo "Foo::testPrivate\n"; } } $myFoo = new foo(); $myFoo->test(); // Bar::testPrivate // Foo::testPublic ?> Visibility from other objects Objects of the same type will have access to each others private and protected members even though they are not the same instances. This is because the implementation specific details are already known when inside those objects. Example #3 Accessing private members of the same object type foo = $foo; } private function bar() { echo 'Accessed the private method.'; } public function baz(Test $other) { // We can change the private property: $other->foo = 'hello'; var_dump($other->foo); // We can also call the private method: $other->bar(); } } $test = new Test('test'); $test->baz(new Test('other')); ?> The above example will output: string(5) "hello" Accessed the private method. ---------------------------------------------------------------------- ---------------------------------------------------------------------- Object Inheritance Inheritance is a well-established programming principle, and PHP makes use of this principle in its object model. This principle will affect the way many classes and objects relate to one another. For example, when you extend a class, the subclass inherits all of the public and protected methods from the parent class. Unless a class overrides those methods, they will retain their original functionality. This is useful for defining and abstracting functionality, and permits the implementation of additional functionality in similar objects without the need to reimplement all of the shared functionality. Note: Unless autoloading is used, then classes must be defined before they are used. If a class extends another, then the parent class must be declared before the child class structure. This rule applies to class that inherit other classes and interfaces. Example #1 Inheritance Example printItem('baz'); // Output: 'Foo: baz' $foo->printPHP(); // Output: 'PHP is great' $bar->printItem('baz'); // Output: 'Bar: baz' $bar->printPHP(); // Output: 'PHP is great' ?> ---------------------------------------------------------------------- ---------------------------------------------------------------------- Scope Resolution Operator (::) The Scope Resolution Operator (also called Paamayim Nekudotayim) or in simpler terms, the double colon, is a token that allows access to static, constant, and overridden properties or methods of a class. When referencing these items from outside the class definition, use the name of the class. As of PHP 5.3.0, it's possible to reference the class using a variable. The variable's value can not be a keyword (e.g. self, parent and static). Paamayim Nekudotayim would, at first, seem like a strange choice for naming a double-colon. However, while writing the Zend Engine 0.5 (which powers PHP 3), that's what the Zend team decided to call it. It actually does mean double-colon - in Hebrew! Example #1 :: from outside the class definition Two special keywords self and parent are used to access properties or methods from inside the class definition. Example #2 :: from inside the class definition When an extending class overrides the parents definition of a method, PHP will not call the parent's method. It's up to the extended class on whether or not the parent's method is called. This also applies to Constructors and Destructors, Overloading, and Magic method definitions. Example #3 Calling a parent's method myFunc(); ?> ---------------------------------------------------------------------- ---------------------------------------------------------------------- Static Keyword Declaring class properties or methods as static makes them accessible without needing an instantiation of the class. A property declared as static can not be accessed with an instantiated class object (though a static method can). For compatibility with PHP 4, if no visibility declaration is used, then the property or method will be treated as if it was declared as public. Because static methods are callable without an instance of the object created, the pseudo-variable $this is not available inside the method declared as static. Static properties cannot be accessed through the object using the arrow operator ->. Calling non-static methods statically generates an E_STRICT level warning. Like any other PHP static variable, static properties may only be initialized using a literal or constant; expressions are not allowed. So while you may initialize a static property to an integer or array (for instance), you may not initialize it to another variable, to a function return value, or to an object. As of PHP 5.3.0, it's possible to reference the class using a variable. The variable's value can not be a keyword (e.g. self, parent and static). Example #1 Static property example staticValue() . "\n"; print $foo->my_static . "\n"; // Undefined "Property" my_static print $foo::$my_static . "\n"; $classname = 'Foo'; print $classname::$my_static . "\n"; // As of PHP 5.3.0 print Bar::$my_static . "\n"; $bar = new Bar(); print $bar->fooStatic() . "\n"; ?> Example #2 Static method example ---------------------------------------------------------------------- ---------------------------------------------------------------------- Class Abstraction PHP 5 introduces abstract classes and methods. Classes defined as abstract may not be instantiated, and any class that contains at least one abstract method must also be abstract. Methods defined as abstract simply declare the method's signature - they cannot define the implementation. When inheriting from an abstract class, all methods marked abstract in the parent's class declaration must be defined by the child; additionally, these methods must be defined with the same (or a less restricted) visibility. For example, if the abstract method is defined as protected, the function implementation must be defined as either protected or public, but not private. Example #1 Abstract class example getValue() . "\n"; } } class ConcreteClass1 extends AbstractClass { protected function getValue() { return "ConcreteClass1"; } public function prefixValue($prefix) { return "{$prefix}ConcreteClass1"; } } class ConcreteClass2 extends AbstractClass { public function getValue() { return "ConcreteClass2"; } public function prefixValue($prefix) { return "{$prefix}ConcreteClass2"; } } $class1 = new ConcreteClass1; $class1->printOut(); echo $class1->prefixValue('FOO_') ."\n"; $class2 = new ConcreteClass2; $class2->printOut(); echo $class2->prefixValue('FOO_') ."\n"; ?> The above example will output: ConcreteClass1 FOO_ConcreteClass1 ConcreteClass2 FOO_ConcreteClass2 Old code that has no user-defined classes or functions named 'abstract' should run without modifications. ---------------------------------------------------------------------- ---------------------------------------------------------------------- Object Interfaces Object interfaces allow you to create code which specifies which methods a class must implement, without having to define how these methods are handled. Interfaces are defined using the interface keyword, in the same way as a standard class, but without any of the methods having their contents defined. All methods declared in an interface must be public, this is the nature of an interface. implements To implement an interface, the implements operator is used. All methods in the interface must be implemented within a class; failure to do so will result in a fatal error. Classes may implement more than one interface if desired by separating each interface with a comma. Note: A class cannot implement two interfaces that share function names, since it would cause ambiguity. Note: Interfaces can be extended like classes using the extends operator. Note: The class implementing the interface must use the exact same method signatures as are defined in the interface. Not doing so will result in a fatal error. Constants Its possible for interfaces to have constants. Interface constants works exactly like class constants except they cannot be overridden by a class/interface that inherits it. Examples Example #1 Interface example vars[$name] = $var; } public function getHtml($template) { foreach($this->vars as $name => $value) { $template = str_replace('{' . $name . '}', $value, $template); } return $template; } } // This will not work // Fatal error: Class BadTemplate contains 1 abstract methods // and must therefore be declared abstract (iTemplate::getHtml) class BadTemplate implements iTemplate { private $vars = array(); public function setVariable($name, $var) { $this->vars[$name] = $var; } } ?> Example #2 Extendable Interfaces Example #3 Multiple interface inheritance Example #4 Interfaces with constants An interface, together with type-hinting, provides a good way to make sure that a particular object contains particular methods. See instanceof operator and type hinting. ---------------------------------------------------------------------- ---------------------------------------------------------------------- Overloading Overloading in PHP provides means to dynamically "create" properties and methods. These dynamic entities are processed via magic methods one can establish in a class for various action types. The overloading methods are invoked when interacting with properties or methods that have not been declared or are not visible in the current scope. The rest of this section will use the terms "inaccessible properties" and "inaccessible methods" to refer to this combination of declaration and visibility. All overloading methods must be defined as public. Note: None of the arguments of these magic methods can be passed by reference. Note: PHP's interpretation of "overloading" is different than most object oriented languages. Overloading traditionally provides the ability to have multiple methods with the same name but different quantities and types of arguments. Changelog Version Description 5.3.0 Added __callStatic(). Added warning to enforce public visibility and non-static declaration. 5.1.0 Added __isset() and __unset(). Property overloading void __set ( string $name , mixed $value ) mixed __get ( string $name ) bool __isset ( string $name ) void __unset ( string $name ) __set() is run when writing data to inaccessible properties. __get() is utilized for reading data from inaccessible properties. __isset() is triggered by calling isset() or empty() on inaccessible properties. __unset() is invoked when unset() is used on inaccessible properties. The $name argument is the name of the property being interacted with. The __set() method's $value argument specifies the value the $name'ed property should be set to. Property overloading only works in object context. These magic methods will not be triggered in static context. Therefore these methods should not be declared static. As of PHP 5.3.0, a warning is issued if one of the magic overloading methods is declared static. Note: The return value of __set() is ignored because of the way PHP processes the assignment operator. Similarly, __get() is never called when chaining assignments together like this: $a = $obj->b = 8; Note: It is not possible to use overloaded properties in other language constructs than isset(). This means if empty() is called on an overloaded property, the overloaded method is not called. To workaround that limitation, the overloaded property must be copied into a local variable in the scope and then be handed to empty(). Example #1 Overloading properties via the __get(), __set(), __isset() and __unset() methods data[$name] = $value; } public function __get($name) { echo "Getting '$name'\n"; if (array_key_exists($name, $this->data)) { return $this->data[$name]; } $trace = debug_backtrace(); trigger_error( 'Undefined property via __get(): ' . $name . ' in ' . $trace[0]['file'] . ' on line ' . $trace[0]['line'], E_USER_NOTICE); return null; } /** As of PHP 5.1.0 */ public function __isset($name) { echo "Is '$name' set?\n"; return isset($this->data[$name]); } /** As of PHP 5.1.0 */ public function __unset($name) { echo "Unsetting '$name'\n"; unset($this->data[$name]); } /** Not a magic method, just here for example. */ public function getHidden() { return $this->hidden; } } echo "
\n";

   $obj = new PropertyTest;

   $obj->a = 1;
   echo $obj->a . "\n\n";

   var_dump(isset($obj->a));
   unset($obj->a);
   var_dump(isset($obj->a));
   echo "\n";

   echo $obj->declared . "\n\n";

   echo "Let's experiment with the private property named 'hidden':\n";
   echo "Privates are visible inside the class, so __get() not used...\n";
   echo $obj->getHidden() . "\n";
   echo "Privates not visible outside of class, so __get() is used...\n";
   echo $obj->hidden . "\n";
   ?>

   The above example will output:

 Setting 'a' to '1'
 Getting 'a'
 1

 Is 'a' set?
 bool(true)
 Unsetting 'a'
 Is 'a' set?
 bool(false)

 1

 Let's experiment with the private property named 'hidden':
 Privates are visible inside the class, so __get() not used...
 2
 Privates not visible outside of class, so __get() is used...
 Getting 'hidden'


 Notice:  Undefined property via __get(): hidden in  on line 70 in  on line 29

  Method overloading

   mixed __call ( string $name , array $arguments )
   mixed __callStatic ( string $name , array $arguments )

   __call() is triggered when invoking inaccessible methods in an object
   context.

   __callStatic() is triggered when invoking inaccessible methods in a static
   context.

   The $name argument is the name of the method being called. The $arguments
   argument is an enumerated array containing the parameters passed to the
   $name'ed method.

   Example #2 Overloading methods via the __call() and __callStatic() methods

   runTest('in object context');

   MethodTest::runTest('in static context');  // As of PHP 5.3.0
   ?>

   The above example will output:

 Calling object method 'runTest' in object context
 Calling static method 'runTest' in static context

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

Object Iteration

   PHP 5 provides a way for objects to be defined so it is possible to
   iterate through a list of items, with, for example a foreach statement. By
   default, all visible properties will be used for the iteration.

   Example #1 Simple Object Iteration

    $value) {
              print "$key => $value\n";
          }
       }
   }

   $class = new MyClass();

   foreach($class as $key => $value) {
       print "$key => $value\n";
   }
   echo "\n";

   $class->iterateVisible();

   ?>

   The above example will output:

 var1 => value 1
 var2 => value 2
 var3 => value 3

 MyClass::iterateVisible:
 var1 => value 1
 var2 => value 2
 var3 => value 3
 protected => protected var
 private => private var

   As the output shows, the foreach iterated through all visible variables
   that can be accessed. To take it a step further you can implement one of
   PHP 5's internal interface named Iterator. This allows the object to
   decide what and how the object will be iterated.

   Example #2 Object Iteration implementing Iterator

   var = $array;
           }
       }

       public function rewind()
       {
           echo "rewinding\n";
           reset($this->var);
       }
     
       public function current()
       {
           $var = current($this->var);
           echo "current: $var\n";
           return $var;
       }
     
       public function key() 
       {
           $var = key($this->var);
           echo "key: $var\n";
           return $var;
       }
     
       public function next() 
       {
           $var = next($this->var);
           echo "next: $var\n";
           return $var;
       }
     
       public function valid()
       {
           $key = key($this->var);
           $var = ($key !== NULL && $key !== FALSE);
           echo "valid: $var\n";
           return $var;
       }

   }

   $values = array(1,2,3);
   $it = new MyIterator($values);

   foreach ($it as $a => $b) {
       print "$a: $b\n";
   }
   ?>

   The above example will output:

 rewinding
 valid: 1
 current: 1
 key: 0
 0: 1
 next: 2
 valid: 1
 current: 2
 key: 1
 1: 2
 next: 3
 valid: 1
 current: 3
 key: 2
 2: 3
 next:
 valid:

   You can also define your class so that it doesn't have to define all the
   Iterator functions by simply implementing the PHP 5 IteratorAggregate
   interface.

   Example #3 Object Iteration implementing IteratorAggregate

   items);
       }

       public function add($value) {
           $this->items[$this->count++] = $value;
       }
   }

   $coll = new MyCollection();
   $coll->add('value 1');
   $coll->add('value 2');
   $coll->add('value 3');

   foreach ($coll as $key => $val) {
       echo "key/value: [$key -> $val]\n\n";
   }
   ?>

   The above example will output:

 rewinding
 current: value 1
 valid: 1
 current: value 1
 key: 0
 key/value: [0 -> value 1]

 next: value 2
 current: value 2
 valid: 1
 current: value 2
 key: 1
 key/value: [1 -> value 2]

 next: value 3
 current: value 3
 valid: 1
 current: value 3
 key: 2
 key/value: [2 -> value 3]

 next:
 current:
 valid:

     Note:

     For more examples of iterators, see the SPL Extension.

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

Patterns

   Patterns are ways to describe best practices and good designs. They show a
   flexible solution to common programming problems.

  Factory

   The Factory pattern allows for the instantiation of objects at runtime. It
   is called a Factory Pattern since it is responsible for "manufacturing" an
   object. A Parameterized Factory receives the name of the class to
   instantiate as argument.

   Example #1 Parameterized Factory Method

   

   Defining this method in a class allows drivers to be loaded on the fly. If
   the Example class was a database abstraction class, loading a MySQL and
   SQLite driver could be done as follows:

   

  Singleton

   The Singleton ensures that there can be only one instance of a Class and
   provides a global access point to that instance. Singleton is a "Gang of
   Four" Creational Pattern.

   The Singleton pattern is often implemented in Database Classes, Loggers,
   Front Controllers or Request and Response objects.

   Example #2 Singleton example

   count++;
       }

       public function __clone()
       {
           trigger_error('Clone is not allowed.', E_USER_ERROR);
       }

       public function __wakeup()
       {
           trigger_error('Unserializing is not allowed.', E_USER_ERROR);
       }
   }
   ?>

   Illustrated below is how the Singleton behaves

   increment(); // 0
   echo $singleton->increment(); // 1

   $singleton = Example::singleton(); // reuses existing instance now
   echo $singleton->increment(); // 2
   echo $singleton->increment(); // 3

   // all of these will raise a Fatal Error
   $singleton2 = new Example;
   $singleton3 = clone $singleton;
   $singleton4 = unserialize(serialize($singleton));
   ?>
   Warning

   The Singleton pattern is one of the more controversial patterns. Critics
   argue that Singletons introduce Global State into an application and
   tightly couple the Singleton and its consuming classes. This leads to
   hidden dependencies and unexpected side-effects, which in turn leads to
   code that is harder to test and maintain.

   Critics further argue that it is pointless to use a Singleton in a Shared
   Nothing Architecture like PHP where objects are unique within the Request
   only anyways. It is easier and cleaner to create collaborator object
   graphs by using Builders and Factory patterns once at the beginning of the
   Request.

   Singletons also violate several of the "SOLID" OOP design principles and
   the Law of Demeter. Singletons cannot be serialized. They cannot be
   subtyped (before PHP 5.3) and won't be Garbage Collected because of the
   instance being stored as a static attribute of the Singleton.

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

Magic Methods

   The function names __construct, __destruct, __call, __callStatic, __get,
   __set, __isset, __unset, __sleep, __wakeup, __toString, __invoke,
   __set_state and __clone are magical in PHP classes. You cannot have
   functions with these names in any of your classes unless you want the
   magic functionality associated with them.

   Caution

   PHP reserves all function names starting with __ as magical. It is
   recommended that you do not use function names with __ in PHP unless you
   want some documented magic functionality.

  __sleep and __wakeup

   serialize() checks if your class has a function with the magic name
   __sleep. If so, that function is executed prior to any serialization. It
   can clean up the object and is supposed to return an array with the names
   of all variables of that object that should be serialized. If the method
   doesn't return anything then NULL is serialized and E_NOTICE is issued.

     Note:

     It is not possible for __sleep to return names of private properties in
     parent classes. Doing this will result in an E_NOTICE level error.
     Instead you may use the Serializable interface.

   The intended use of __sleep is to commit pending data or perform similar
   cleanup tasks. Also, the function is useful if you have very large objects
   which do not need to be saved completely.

   Conversely, unserialize() checks for the presence of a function with the
   magic name __wakeup. If present, this function can reconstruct any
   resources that the object may have.

   The intended use of __wakeup is to reestablish any database connections
   that may have been lost during serialization and perform other
   reinitialization tasks.

   Example #1 Sleep and wakeup

   server = $server;
           $this->username = $username;
           $this->password = $password;
           $this->db = $db;
           $this->connect();
       }
       
       private function connect()
       {
           $this->link = mysql_connect($this->server, $this->username, $this->password);
           mysql_select_db($this->db, $this->link);
       }
       
       public function __sleep()
       {
           return array('server', 'username', 'password', 'db');
       }
       
       public function __wakeup()
       {
           $this->connect();
       }
   }
   ?>

  __toString

   The __toString method allows a class to decide how it will react when it
   is treated like a string. For example, what echo $obj; will print. This
   method must return a string, as otherwise a fatal E_RECOVERABLE_ERROR
   level error is emitted.

   Example #2 Simple example

   foo = $foo;
       }

       public function __toString()
       {
           return $this->foo;
       }
   }

   $class = new TestClass('Hello');
   echo $class;
   ?>

   The above example will output:

 Hello

   It is worth noting that before PHP 5.2.0 the __toString method was only
   called when it was directly combined with echo() or print(). Since PHP
   5.2.0, it is called in any string context (e.g. in printf() with %s
   modifier) but not in other types contexts (e.g. with %d modifier). Since
   PHP 5.2.0, converting objects without __toString method to string would
   cause E_RECOVERABLE_ERROR.

  __invoke

   The __invoke method is called when a script tries to call an object as a
   function.

     Note:

     This feature is available since PHP 5.3.0.

   Example #3 Using __invoke

   

   The above example will output:

 int(5)
 bool(true)

  __set_state

   This static method is called for classes exported by var_export() since
   PHP 5.1.0.

   The only parameter of this method is an array containing exported
   properties in the form array('property' => value, ...).

   Example #4 Using __set_state (since PHP 5.1.0)

   var1 = $an_array['var1'];
           $obj->var2 = $an_array['var2'];
           return $obj;
       }
   }

   $a = new A;
   $a->var1 = 5;
   $a->var2 = 'foo';

   eval('$b = ' . var_export($a, true) . ';'); // $b = A::__set_state(array(
                                               //    'var1' => 5,
                                               //    'var2' => 'foo',
                                               // ));
   var_dump($b);

   ?>

   The above example will output:

 object(A)#2 (2) {
   ["var1"]=>
   int(5)
   ["var2"]=>
   string(3) "foo"
 }

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

Final Keyword

   PHP 5 introduces the final keyword, which prevents child classes from
   overriding a method by prefixing the definition with final. If the class
   itself is being defined final then it cannot be extended.

   Example #1 Final methods example

   

   Example #2 Final class example

   

     Note: Properties cannot be declared final, only classes and methods may
     be declared as final.

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

Object Cloning

   Creating a copy of an object with fully replicated properties is not
   always the wanted behavior. A good example of the need for copy
   constructors, is if you have an object which represents a GTK window and
   the object holds the resource of this GTK window, when you create a
   duplicate you might want to create a new window with the same properties
   and have the new object hold the resource of the new window. Another
   example is if your object holds a reference to another object which it
   uses and when you replicate the parent object you want to create a new
   instance of this other object so that the replica has its own separate
   copy.

   An object copy is created by using the clone keyword (which calls the
   object's __clone() method if possible). An object's __clone() method
   cannot be called directly.

 $copy_of_object = clone $object;

   When an object is cloned, PHP 5 will perform a shallow copy of all of the
   object's properties. Any properties that are references to other
   variables, will remain references.

   Once the cloning is complete, if a __clone() method is defined, then the
   newly created object's __clone() method will be called, to allow any
   necessary properties that need to be changed.

   Example #1 Cloning an object

   instance = ++self::$instances;
       }

       public function __clone() {
           $this->instance = ++self::$instances;
       }
   }

   class MyCloneable
   {
       public $object1;
       public $object2;

       function __clone()
       {
           // Force a copy of this->object, otherwise
           // it will point to same object.
           $this->object1 = clone $this->object1;
       }
   }

   $obj = new MyCloneable();

   $obj->object1 = new SubObject();
   $obj->object2 = new SubObject();

   $obj2 = clone $obj;

   print("Original Object:\n");
   print_r($obj);

   print("Cloned Object:\n");
   print_r($obj2);

   ?>

   The above example will output:

 Original Object:
 MyCloneable Object
 (
     [object1] => SubObject Object
         (
             [instance] => 1
         )

     [object2] => SubObject Object
         (
             [instance] => 2
         )

 )
 Cloned Object:
 MyCloneable Object
 (
     [object1] => SubObject Object
         (
             [instance] => 3
         )

     [object2] => SubObject Object
         (
             [instance] => 2
         )

 )

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

Comparing Objects

   In PHP 5, object comparison is more complicated than in PHP 4 and more in
   accordance to what one will expect from an Object Oriented Language (not
   that PHP 5 is such a language).

   When using the comparison operator (==), object variables are compared in
   a simple manner, namely: Two object instances are equal if they have the
   same attributes and values, and are instances of the same class.

   On the other hand, when using the identity operator (===), object
   variables are identical if and only if they refer to the same instance of
   the same class.

   An example will clarify these rules.

   Example #1 Example of object comparison in PHP 5

   flag = $flag;
       }
   }

   class OtherFlag
   {
       public $flag;

       function OtherFlag($flag = true) {
           $this->flag = $flag;
       }
   }

   $o = new Flag();
   $p = new Flag();
   $q = $o;
   $r = new OtherFlag();

   echo "Two instances of the same class\n";
   compareObjects($o, $p);

   echo "\nTwo references to the same instance\n";
   compareObjects($o, $q);

   echo "\nInstances of two different classes\n";
   compareObjects($o, $r);
   ?>

   The above example will output:

 Two instances of the same class
 o1 == o2 : TRUE
 o1 != o2 : FALSE
 o1 === o2 : FALSE
 o1 !== o2 : TRUE

 Two references to the same instance
 o1 == o2 : TRUE
 o1 != o2 : FALSE
 o1 === o2 : TRUE
 o1 !== o2 : FALSE

 Instances of two different classes
 o1 == o2 : FALSE
 o1 != o2 : TRUE
 o1 === o2 : FALSE
 o1 !== o2 : TRUE

     Note:

     Extensions can define own rules for their objects comparison.

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

Type Hinting

   PHP 5 introduces Type Hinting. Functions are now able to force parameters
   to be objects (by specifying the name of the class in the function
   prototype) or arrays (since PHP 5.1). However, if NULL is used as the
   default parameter value, it will be allowed as an argument for any later
   call.

   Example #1 Type Hinting examples

   var;
       }

       /**
        * Another test function
        *
        * First parameter must be an array
        */
       public function test_array(array $input_array) {
           print_r($input_array);
       }
   }

   // Another example class
   class OtherClass {
       public $var = 'Hello World';
   }
   ?>

   Failing to satisfy the type hint results in a catchable fatal error.

   test('hello');

   // Fatal Error: Argument 1 must be an instance of OtherClass
   $foo = new stdClass;
   $myclass->test($foo);

   // Fatal Error: Argument 1 must not be null
   $myclass->test(null);

   // Works: Prints Hello World
   $myclass->test($otherclass);

   // Fatal Error: Argument 1 must be an array
   $myclass->test_array('a string');

   // Works: Prints the array
   $myclass->test_array(array('a', 'b', 'c'));
   ?>

   Type hinting also works with functions:

   var;
   }

   // Works
   $myclass = new MyClass;
   MyFunction($myclass);
   ?>

   Type hinting allowing NULL value:

   

   Type Hints can only be of the object and array (since PHP 5.1) type.
   Traditional type hinting with int and string isn't supported.

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

Late Static Bindings

   As of PHP 5.3.0, PHP implements a feature called late static bindings
   which can be used to reference the called class in a context of static
   inheritance.

   More precisely, late static bindings work by storing the class named in
   the last "non-forwarding call". In case of static method calls, this is
   the class explicitly named (usually the one on the left of the ::
   operator); in case of non static method calls, it is the class of the
   object. A "forwarding call" is a static one that is introduced by self::,
   parent::, static::, or, if going up in the class hierarchy,
   forward_static_call(). The function get_called_class() can be used to
   retrieve a string with the name of the called class and static::
   introduces its scope.

   This feature was named "late static bindings" with an internal perspective
   in mind. "Late binding" comes from the fact that static:: will not be
   resolved using the class where the method is defined but it will rather be
   computed using runtime information. It was also called a "static binding"
   as it can be used for (but is not limited to) static method calls.

  Limitations of self::

   Static references to the current class like self:: or __CLASS__ are
   resolved using the class in which the function belongs, as in where it was
   defined:

   Example #1 self:: usage

   

   The above example will output:

 A

  Late Static Bindings' usage

   Late static bindings tries to solve that limitation by introducing a
   keyword that references the class that was initially called at runtime.
   Basically, a keyword that would allow you to reference B from test() in
   the previous example. It was decided not to introduce a new keyword but
   rather use static that was already reserved.

   Example #2 static:: simple usage

   

   The above example will output:

 B

     Note:

     In non-static contexts, the called class will be the class of the object
     instance. Since $this-> will try to call private methods from the same
     scope, using static:: may give different results. Another difference is
     that static:: can only refer to static properties.

   Example #3 static:: usage in a non-static context

   foo();
           static::foo();
       }
   }

   class B extends A {
      /* foo() will be copied to B, hence its scope will still be A and
       * the call be successful */
   }

   class C extends A {
       private function foo() {
           /* original method is replaced; the scope of the new one is C */
       }
   }

   $b = new B();
   $b->test();
   $c = new C();
   $c->test();   //fails
   ?>

   The above example will output:

 success!
 success!
 success!


 Fatal error:  Call to private method C::foo() from context 'A' in /tmp/test.php on line 9

     Note:

     Late static bindings' resolution will stop at a fully resolved static
     call with no fallback. On the other hand, static calls using keywords
     like parent:: or self:: will forward the calling information.

     Example #4 Forwarding and non-forwarding calls

     

     The above example will output:

 A
 C
 C

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

Objects and references

   One of the key-points of PHP5 OOP that is often mentioned is that "objects
   are passed by references by default". This is not completely true. This
   section rectifies that general thought using some examples.

   A PHP reference is an alias, which allows two different variables to write
   to the same value. As of PHP5, an object variable doesn't contain the
   object itself as value anymore. It only contains an object identifier
   which allows object accessors to find the actual object. When an object is
   sent by argument, returned or assigned to another variable, the different
   variables are not aliases: they hold a copy of the identifier, which
   points to the same object.

   Example #1 References and Objects

   
   $b->foo = 2;
   echo $a->foo."\n";

   $c = new A;
   $d = &$c;    // $c and $d are references
                // ($c,$d) = 

   $d->foo = 2;
   echo $c->foo."\n";

   $e = new A;

   function foo($obj) {
       // ($obj) = ($e) = 
       $obj->foo = 2;
   }

   foo($e);
   echo $e->foo."\n";

   ?>

   The above example will output:

 2
 2
 2

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

Object Serialization

Serializing objects - objects in sessions

   serialize() returns a string containing a byte-stream representation of
   any value that can be stored in PHP. unserialize() can use this string to
   recreate the original variable values. Using serialize to save an object
   will save all variables in an object. The methods in an object will not be
   saved, only the name of the class.

   In order to be able to unserialize() an object, the class of that object
   needs to be defined. That is, if you have an object of class A and
   serialize this, you'll get a string that refers to class A and contains
   all values of variables contained in it. If you want to be able to
   unserialize this in another file, an object of class A, the definition of
   class A must be present in that file first. This can be done for example
   by storing the class definition of class A in an include file and
   including this file or making use of the spl_autoload_register() function.

   one;
         }
     }
     
   // page1.php:

     include("classa.inc");
     
     $a = new A;
     $s = serialize($a);
     // store $s somewhere where page2.php can find it.
     file_put_contents('store', $s);

   // page2.php:
     
     // this is needed for the unserialize to work properly.
     include("classa.inc");

     $s = file_get_contents('store');
     $a = unserialize($s);

     // now use the function show_one() of the $a object.  
     $a->show_one();
   ?>

   If an application is using sessions and uses session_register() to
   register objects, these objects are serialized automatically at the end of
   each PHP page, and are unserialized automatically on each of the following
   pages. This means that these objects can show up on any of the
   application's pages once they become part of the session. However, the
   session_register() is removed since PHP 5.4.0.

   It is strongly recommended that if an application serializes objects, for
   use later in the application, that the application include the class
   definition for that object throughout the application. Not doing so might
   result in an object being unserialized without a class definition, which
   will result in PHP giving the object a class of
   __PHP_Incomplete_Class_Name, which has no methods and would render the
   object useless.

   So if in the example above $a became part of a session by running
   session_register("a"), you should include the file classa.inc on all of
   your pages, not only page1.php and page2.php.

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

OOP Changelog

   Changes to the PHP 5 OOP model are logged here. Descriptions and other
   notes regarding these features are documented within the OOP 5
   documentation.

   Version                            Description                             
           Changed: Methods with the same name as the last element of a       
   5.3.3   namespaced class name will no longer be treated as constructor.    
           This change doesn't affect non-namespaced classes.                 
           Changed: Classes that implement interfaces with methods that have  
   5.3.0   default values in the prototype are no longer required to match    
           the interface's default value.                                     
           Changed: It's now possible to reference the class using a variable 
   5.3.0   (e.g., echo $classname::constant;). The variable's value can not   
           be a keyword (e.g., self, parent or static).                       
           Changed: An E_WARNING level error is issued if the magic           
   5.3.0   overloading methods are declared static. It also enforces the      
           public visibility requirement.                                     
           Changed: Prior to 5.3.0, exceptions thrown in the __autoload       
           function could not be caught in the catch block, and would result  
           in a fatal error. Exceptions now thrown in the __autoload function 
   5.3.0   can be caught in the catch block, with one proviso. If throwing a  
           custom exception, then the custom exception class must be          
           available. The __autoload function may be used recursively to      
           autoload the custom exception class.                               
   5.3.0   Added: The __callStatic method.                                    
           Added: heredoc and nowdoc support for class const and property     
   5.3.0   definitions. Note: heredoc values must follow the same rules as    
           double-quoted strings, (e.g., no variables within).                
   5.3.0   Added: Late Static Bindings.                                       
   5.3.0   Added: The __invoke method.                                        
           Changed: The __toString method was only called when it was         
           directly combined with echo() or print(). But now, it is called in 
   5.2.0   any string context (e.g. in printf() with %s modifier) but not in  
           other types contexts (e.g. with %d modifier). Since PHP 5.2.0,     
           converting objects without a __toString method to string emits a   
           E_RECOVERABLE_ERROR level error.                                   
           Changed: In previous versions of PHP 5, the use of var was         
   5.1.3   considered deprecated and would issue an E_STRICT level error.     
           It's no longer deprecated, therefore does not emit the error.      
   5.1.0   Changed: The __set_state static method is now called for classes   
           exported by var_export().                                          
   5.1.0   Added: The __isset and __unset methods.                            

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

                                   Namespaces

Table of Contents

     * Namespaces overview
     * Defining namespaces
     * Declaring sub-namespaces
     * Defining multiple namespaces in the same file
     * Using namespaces: Basics
     * Namespaces and dynamic language features
     * namespace keyword and __NAMESPACE__ constant
     * Using namespaces: Aliasing/Importing
     * Global space
     * Using namespaces: fallback to global function/constant
     * Name resolution rules
     * FAQ: things you need to know about namespaces

     ----------------------------------------------------------------------

Namespaces overview

   What are namespaces? In the broadest definition namespaces are a way of
   encapsulating items. This can be seen as an abstract concept in many
   places. For example, in any operating system directories serve to group
   related files, and act as a namespace for the files within them. As a
   concrete example, the file foo.txt can exist in both directory /home/greg
   and in /home/other, but two copies of foo.txt cannot co-exist in the same
   directory. In addition, to access the foo.txt file outside of the
   /home/greg directory, we must prepend the directory name to the file name
   using the directory separator to get /home/greg/foo.txt. This same
   principle extends to namespaces in the programming world.

   In the PHP world, namespaces are designed to solve two problems that
   authors of libraries and applications encounter when creating re-usable
   code elements such as classes or functions:

    1. Name collisions between code you create, and internal PHP
       classes/functions/constants or third-party
       classes/functions/constants.
    2. Ability to alias (or shorten) Extra_Long_Names designed to alleviate
       the first problem, improving readability of source code.

   PHP Namespaces provide a way in which to group related classes, functions
   and constants. Here is an example of namespace syntax in PHP:

   Example #1 Namespace syntax example

   

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

Defining namespaces

   Although any valid PHP code can be contained within a namespace, only
   three type of code are affected by namespaces: classes, functions and
   constants.

   Namespaces are declared using the namespace keyword. A file containing a
   namespace must declare the namespace at the top of the file before any
   other code - with one exception: the declare keyword.

   Example #1 Declaring a single namespace

   
   The only code construct allowed before a namespace declaration is the
   declare statement, for defining encoding of a source file. In addition, no
   non-PHP code may precede a namespace declaration, including extra
   whitespace:

   Example #2 Declaring a single namespace

   
   

   In addition, unlike any other PHP construct, the same namespace may be
   defined in multiple files, allowing splitting up of a namespace's contents
   across the filesystem.

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

Declaring sub-namespaces

   Much like directories and files, PHP namespaces also contain the ability
   to specify a hierarchy of namespace names. Thus, a namespace name can be
   defined with sub-levels:

   Example #1 Declaring a single namespace with hierarchy

   
   The above example creates constant MyProject\Sub\Level\CONNECT_OK, class
   MyProject\Sub\Level\Connection and function MyProject\Sub\Level\connect.

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

Defining multiple namespaces in the same file

   Multiple namespaces may also be declared in the same file. There are two
   allowed syntaxes.

   Example #1 Declaring multiple namespaces, simple combination syntax

   

   This syntax is not recommended for combining namespaces into a single
   file. Instead it is recommended to use the alternate bracketed syntax.

   Example #2 Declaring multiple namespaces, bracketed syntax

   

   It is strongly discouraged as a coding practice to combine multiple
   namespaces into the same file. The primary use case is to combine multiple
   PHP scripts into the same file.

   To combine global non-namespaced code with namespaced code, only bracketed
   syntax is supported. Global code should be encased in a namespace
   statement with no namespace name as in:

   Example #3 Declaring multiple namespaces and unnamespaced code

   

   No PHP code may exist outside of the namespace brackets except for an
   opening declare statement.

   Example #4 Declaring multiple namespaces and unnamespaced code

   

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

Using namespaces: Basics

   Before discussing the use of namespaces, it is important to understand how
   PHP knows which namespaced element your code is requesting. A simple
   analogy can be made between PHP namespaces and a filesystem. There are
   three ways to access a file in a file system:
    1. Relative file name like foo.txt. This resolves to
       currentdirectory/foo.txt where currentdirectory is the directory
       currently occupied. So if the current directory is /home/foo, the name
       resolves to /home/foo/foo.txt.
    2. Relative path name like subdirectory/foo.txt. This resolves to
       currentdirectory/subdirectory/foo.txt.
    3. Absolute path name like /main/foo.txt. This resolves to /main/foo.txt.
   The same principle can be applied to namespaced elements in PHP. For
   example, a class name can be referred to in three ways:
    1. Unqualified name, or an unprefixed class name like $a = new foo(); or
       foo::staticmethod();. If the current namespace is currentnamespace,
       this resolves to currentnamespace\foo. If the code is global,
       non-namespaced code, this resolves to foo. One caveat: unqualified
       names for functions and constants will resolve to global functions and
       constants if the namespaced function or constant is not defined. See
       Using namespaces: fallback to global function/constant for details.
    2. Qualified name, or a prefixed class name like $a = new
       subnamespace\foo(); or subnamespace\foo::staticmethod();. If the
       current namespace is currentnamespace, this resolves to
       currentnamespace\subnamespace\foo. If the code is global,
       non-namespaced code, this resolves to subnamespace\foo.
    3. Fully qualified name, or a prefixed name with global prefix operator
       like $a = new \currentnamespace\foo(); or
       \currentnamespace\foo::staticmethod();. This always resolves to the
       literal name specified in the code, currentnamespace\foo.

   Here is an example of the three kinds of syntax in actual code:

   file1.php

   

   file2.php

   

   Note that to access any global class, function or constant, a fully
   qualified name can be used, such as \strlen() or \Exception or \INI_ALL.

   Example #1 Accessing global classes, functions and constants from within a
   namespace

   

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

Namespaces and dynamic language features

   PHP's implementation of namespaces is influenced by its dynamic nature as
   a programming language. Thus, to convert code like the following example
   into namespaced code:

   Example #1 Dynamically accessing elements

   example1.php:

   
   One must use the fully qualified name (class name with namespace prefix).
   Note that because there is no difference between a qualified and a fully
   qualified Name inside a dynamic class name, function name, or constant
   name, the leading backslash is not necessary.

   Example #2 Dynamically accessing namespaced elements

   

   Be sure to read the note about escaping namespace names in strings.

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

namespace keyword and __NAMESPACE__ constant

   PHP supports two ways of abstractly accessing elements within the current
   namespace, the __NAMESPACE__ magic constant, and the namespace keyword.

   The value of __NAMESPACE__ is a string that contains the current namespace
   name. In global, un-namespaced code, it contains an empty string.

   Example #1 __NAMESPACE__ example, namespaced code

   

   Example #2 __NAMESPACE__ example, global code

   
   The __NAMESPACE__ constant is useful for dynamically constructing names,
   for instance:

   Example #3 using __NAMESPACE__ for dynamic name construction

   

   The namespace keyword can be used to explicitly request an element from
   the current namespace or a sub-namespace. It is the namespace equivalent
   of the self operator for classes.

   Example #4 the namespace operator, inside a namespace

   

   Example #5 the namespace operator, in global code

   

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

Using namespaces: Aliasing/Importing

   The ability to refer to an external fully qualified name with an alias, or
   importing, is an important feature of namespaces. This is similar to the
   ability of unix-based filesystems to create symbolic links to a file or to
   a directory.

   PHP namespaces support three kinds of aliasing or importing: aliasing a
   class name, aliasing an interface name, and aliasing a namespace name.
   Note that importing a function or constant is not supported.

   In PHP, aliasing is accomplished with the use operator. Here is an example
   showing all 3 kinds of importing:

   Example #1 importing/aliasing with the use operator

   
   Note that for namespaced names (fully qualified namespace names containing
   namespace separator, such as Foo\Bar as opposed to global names that do
   not, such as FooBar), the leading backslash is unnecessary and not
   recommended, as import names must be fully qualified, and are not
   processed relative to the current namespace.

   PHP additionally supports a convenience shortcut to place multiple use
   statements on the same line

   Example #2 importing/aliasing with the use operator, multiple use
   statements combined

   

   Importing is performed at compile-time, and so does not affect dynamic
   class, function or constant names.

   Example #3 Importing and dynamic names

   

   In addition, importing only affects unqualified and qualified names. Fully
   qualified names are absolute, and unaffected by imports.

   Example #4 Importing and fully qualified names

   

  Scoping rules for importing

   The use keyword must be declared in the outermost scope of a file (the
   global scope) or inside namespace declarations. This is because the
   importing is done at compile time and not runtime, so it cannot be block
   scoped. The following example will show an illegal use of the use keyword:

   Example #5 Illegal importing rule

   

     Note:

     Importing rules are per file basis, meaning included files will NOT
     inherit the parent file's importing rules.

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

Global space

   Without any namespace definition, all class and function definitions are
   placed into the global space - as it was in PHP before namespaces were
   supported. Prefixing a name with \ will specify that the name is required
   from the global space even in the context of the namespace.

   Example #1 Using global space specification

   

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

Using namespaces: fallback to global function/constant

   Inside a namespace, when PHP encounters a unqualified Name in a class
   name, function or constant context, it resolves these with different
   priorities. Class names always resolve to the current namespace name. Thus
   to access internal or non-namespaced user classes, One must refer to them
   with their fully qualified Name as in:

   Example #1 Accessing global classes inside a namespace

   

   For functions and constants, PHP will fall back to global functions or
   constants if a namespaced function or constant does not exist.

   Example #2 global functions/constants fallback inside a namespace

   

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

Name resolution rules

   For the purposes of these resolution rules, here are some important
   definitions:

   Namespace name definitions

   Unqualified name

           This is an identifier without a namespace separator, such as Foo

   Qualified name

           This is an identifier with a namespace separator, such as Foo\Bar

   Fully qualified name

           This is an identifier with a namespace separator that begins with
           a namespace separator, such as \Foo\Bar. namespace\Foo is also a
           fully qualified name.

   Names are resolved following these resolution rules:
    1. Calls to fully qualified functions, classes or constants are resolved
       at compile-time. For instance new \A\B resolves to class A\B.
    2. All unqualified and qualified names (not fully qualified names) are
       translated during compilation according to current import rules. For
       example, if the namespace A\B\C is imported as C, a call to C\D\e() is
       translated to A\B\C\D\e().
    3. Inside a namespace, all qualified names not translated according to
       import rules have the current namespace prepended. For example, if a
       call to C\D\e() is performed within namespace A\B, it is translated to
       A\B\C\D\e().
    4. Unqualified class names are translated during compilation according to
       current import rules (full name substituted for short imported name).
       In example, if the namespace A\B\C is imported as C, new C() is
       translated to new A\B\C().
    5. Inside namespace (say A\B), calls to unqualified functions are
       resolved at run-time. Here is how a call to function foo() is
       resolved:
         1. It looks for a function from the current namespace: A\B\foo().
         2. It tries to find and call the global function foo().
    6. Inside namespace (say A\B), calls to unqualified or qualified class
       names (not fully qualified class names) are resolved at run-time. Here
       is how a call to new C() or new D\E() is resolved. For new C():
         1. It looks for a class from the current namespace: A\B\C.
         2. It attempts to autoload A\B\C.
       For new D\E():
         1. It looks for a class by prepending the current namespace:
            A\B\D\E.
         2. It attempts to autoload A\B\D\E.
       To reference any global class in the global namespace, its fully
       qualified name new \C() must be used.

   Example #1 Name resolutions illustrated

   

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

FAQ: things you need to know about namespaces

   This FAQ is split into two sections: common questions, and some specifics
   of implementation that are helpful to understand fully.

   First, the common questions.
    1. If I don't use namespaces, should I care about any of this?
    2. How do I use internal or global classes in a namespace?
    3. How do I use namespaces classes functions, or constants in their own
       namespace?
    4. How does a name like \my\name or \name resolve?
    5. How does a name like my\name resolve?
    6. How does an unqualified class name like name resolve?
    7. How does an unqualified function name or unqualified constant name
       like name resolve?

   There are a few implementation details of the namespace implementations
   that are helpful to understand.
    1. Import names cannot conflict with classes defined in the same file.
    2. Nested namespaces are not allowed.
    3. Neither functions nor constants can be imported via the use statement.
    4. Dynamic namespace names (quoted identifiers) should escape backslash.
    5. Undefined Constants referenced using any backslash die with fatal
       error
    6. Cannot override special constants NULL, TRUE, FALSE, ZEND_THREAD_SAFE
       or ZEND_DEBUG_BUILD

  If I don't use namespaces, should I care about any of this?

   No. Namespaces do not affect any existing code in any way, or any
   as-yet-to-be-written code that does not contain namespaces. You can write
   this code if you wish:

   Example #1 Accessing global classes outside a namespace

   

   This is functionally equivalent to:

   Example #2 Accessing global classes outside a namespace

   

  How do I use internal or global classes in a namespace?

   Example #3 Accessing internal classes in namespaces

   

  How do I use namespaces classes, functions, or constants in their own
  namespace?

   Example #4 Accessing internal classes, functions or constants in
   namespaces

   

  How does a name like \my\name or \name resolve?

   Names that begin with a \ always resolve to what they look like, so
   \my\name is in fact my\name, and \Exception is Exception.

   Example #5 Fully Qualified names

   

  How does a name like my\name resolve?

   Names that contain a backslash but do not begin with a backslash like
   my\name can be resolved in 2 different ways.

   If there is an import statement that aliases another name to my, then the
   import alias is applied to the my in my\name.

   Otherwise, the current namespace name is prepended to my\name.

   Example #6 Qualified names

   

  How does an unqualified class name like name resolve?

   Class names that do not contain a backslash like name can be resolved in 2
   different ways.

   If there is an import statement that aliases another name to name, then
   the import alias is applied.

   Otherwise, the current namespace name is prepended to name.

   Example #7 Unqualified class names

   

  How does an unqualified function name or unqualified constant name like name
  resolve?

   Function or constant names that do not contain a backslash like name can
   be resolved in 2 different ways.

   First, the current namespace name is prepended to name.

   Finally, if the constant or function name does not exist in the current
   namespace, a global constant or function name is used if it exists.

   Example #8 Unqualified function or constant names

   

  Import names cannot conflict with classes defined in the same file.

   The following script combinations are legal:

   file1.php

   

   another.php

   

   file2.php

   

   There is no name conflict, even though the class MyClass exists within the
   my\stuff namespace, because the MyClass definition is in a separate file.
   However, the next example causes a fatal error on name conflict because
   MyClass is defined in the same file as the use statement.
   

  Nested namespaces are not allowed.

   PHP does not allow nesting namespaces
   
   However, it is easy to simulate nested namespaces like so:
   

  Neither functions nor constants can be imported via the use statement.

   The only elements that are affected by use statements are namespaces and
   class names. In order to shorten a long constant or function, import its
   containing namespace
   

  Dynamic namespace names (quoted identifiers) should escape backslash

   It is very important to realize that because the backslash is used as an
   escape character within strings, it should always be doubled when used
   inside a string. Otherwise there is a risk of unintended consequences:

   Example #9 Dangers of using namespaced names inside a double-quoted string

   
   Inside a single-quoted string, the backslash escape sequence is much safer
   to use, but it is still recommended practice to escape backslashes in all
   strings as a best practice.

  Undefined Constants referenced using any backslash die with fatal error

   Any undefined constant that is unqualified like FOO will produce a notice
   explaining that PHP assumed FOO was the value of the constant. Any
   constant, qualified or fully qualified, that contains a backslash will
   produce a fatal error if not found.

   Example #10 Undefined constants

   

  Cannot override special constants NULL, TRUE, FALSE, ZEND_THREAD_SAFE or
  ZEND_DEBUG_BUILD

   Any attempt to define a namespaced constant that is a special, built-in
   constant results in a fatal error

   Example #11 Undefined constants

   

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

                                   Exceptions

Table of Contents

     * Extending Exceptions

   PHP 5 has an exception model similar to that of other programming
   languages. An exception can be thrown, and caught ("catched") within PHP.
   Code may be surrounded in a try block, to facilitate the catching of
   potential exceptions. Each try must have at least one corresponding catch
   block. Multiple catch blocks can be used to catch different classes of
   exeptions. Normal execution (when no exception is thrown within the try
   block, or when a catch matching the thrown exception's class is not
   present) will continue after that last catch block defined in sequence.
   Exceptions can be thrown (or re-thrown) within a catch block.

   When an exception is thrown, code following the statement will not be
   executed, and PHP will attempt to find the first matching catch block. If
   an exception is not caught, a PHP Fatal Error will be issued with an
   "Uncaught Exception ..." message, unless a handler has been defined with
   set_exception_handler().

   The thrown object must be an instance of the Exception class or a subclass
   of Exception. Trying to throw an object that is not will result in a PHP
   Fatal Error.

     Note:

     Internal PHP functions mainly use Error reporting, only modern Object
     oriented extensions use exceptions. However, errors can be simply
     translated to exceptions with ErrorException.

   Tip

   The Standard PHP Library (SPL) provides a good number of built-in
   exceptions.

   Example #1 Throwing an Exception

   getMessage(), "\n";
   }

   // Continue execution
   echo 'Hello World';
   ?>

   The above example will output:

 0.2
 Caught exception: Division by zero.
 Hello World

   Example #2 Nested Exception

   getMessage());
           }
       }
   }

   $foo = new Test;
   $foo->testing();

   ?>

   The above example will output:

 string(4) "foo!"

     ----------------------------------------------------------------------

Extending Exceptions

   A User defined Exception class can be defined by extending the built-in
   Exception class. The members and properties below, show what is accessible
   within the child class that derives from the built-in Exception class.

   Example #1 The Built in Exception class

   

   If a class extends the built-in Exception class and re-defines the
   constructor, it is highly recommended that it also call
   parent::__construct() to ensure all available data has been properly
   assigned. The __toString() method can be overridden to provide a custom
   output when the object is presented as a string.

     Note:

     Exceptions cannot be cloned. Attempting to clone an Exception will
     result in a fatal E_ERROR error.

   Example #2 Extending the Exception class (PHP 5.3.0+)

   code}]: {$this->message}\n";
       }

       public function customFunction() {
           echo "A custom function for this type of exception\n";
       }
   }

   /**
    * Create a class to test the exception
    */
   class TestException
   {
       public $var;

       const THROW_NONE    = 0;
       const THROW_CUSTOM  = 1;
       const THROW_DEFAULT = 2;

       function __construct($avalue = self::THROW_NONE) {

           switch ($avalue) {
               case self::THROW_CUSTOM:
                   // throw custom exception
                   throw new MyException('1 is an invalid parameter', 5);
                   break;

               case self::THROW_DEFAULT:
                   // throw default one.
                   throw new Exception('2 is not allowed as a parameter', 6);
                   break;

               default: 
                   // No exception, object will be created.
                   $this->var = $avalue;
                   break;
           }
       }
   }

   // Example 1
   try {
       $o = new TestException(TestException::THROW_CUSTOM);
   } catch (MyException $e) {      // Will be caught
       echo "Caught my exception\n", $e;
       $e->customFunction();
   } catch (Exception $e) {        // Skipped
       echo "Caught Default Exception\n", $e;
   }

   // Continue execution
   var_dump($o); // Null
   echo "\n\n";

   // Example 2
   try {
       $o = new TestException(TestException::THROW_DEFAULT);
   } catch (MyException $e) {      // Doesn't match this type
       echo "Caught my exception\n", $e;
       $e->customFunction();
   } catch (Exception $e) {        // Will be caught
       echo "Caught Default Exception\n", $e;
   }

   // Continue execution
   var_dump($o); // Null
   echo "\n\n";

   // Example 3
   try {
       $o = new TestException(TestException::THROW_CUSTOM);
   } catch (Exception $e) {        // Will be caught
       echo "Default Exception caught\n", $e;
   }

   // Continue execution
   var_dump($o); // Null
   echo "\n\n";

   // Example 4
   try {
       $o = new TestException();
   } catch (Exception $e) {        // Skipped, no exception
       echo "Default Exception caught\n", $e;
   }

   // Continue execution
   var_dump($o); // TestException
   echo "\n\n";
   ?>

     Note:

     Versions of PHP 5, prior to PHP 5.3.0 do not support nesting of
     exceptions. The following code fragment can be used as a replacement
     MyException class if you wish to run this example.

     code}]: {$this->message}\n";
         }

         public function customFunction() {
             echo "A custom function for this type of exception\n";
         }
     }
     ?>

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

                              References Explained

Table of Contents

     * What References Are
     * What References Do
     * What References Are Not
     * Passing by Reference
     * Returning References
     * Unsetting References
     * Spotting References

     ----------------------------------------------------------------------

What References Are

   References in PHP are a means to access the same variable content by
   different names. They are not like C pointers; for instance, you cannot
   perform pointer arithmetic using them, they are not actual memory
   addresses, and so on. See What References Are Not for more information.
   Instead, they are symbol table aliases. Note that in PHP, variable name
   and variable content are different, so the same content can have different
   names. The closest analogy is with Unix filenames and files - variable
   names are directory entries, while variable content is the file itself.
   References can be likened to hardlinking in Unix filesystem.

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

What References Do

   There are three basic operations performed using references: assigning by
   reference, passing by reference, and returning by reference. This section
   will give an introduction to these operations, with links to further
   reading.

  Assign By Reference

   In the first of these, PHP references allow you to make two variables
   refer to the same content. Meaning, when you do:
   
   it means that $a and $b point to the same content.

     Note:

     $a and $b are completely equal here. $a is not pointing to $b or vice
     versa. $a and $b are pointing to the same place.

     Note:

     If you assign, pass, or return an undefined variable by reference, it
     will get created.

     Example #1 Using references with undefined variables

     d);
     var_dump(property_exists($c, 'd')); // bool(true)
     ?>

   The same syntax can be used with functions that return references, and
   with the new operator (since PHP 4.0.4 and before PHP 5.0.0):
   
   Since PHP 5, new returns a reference automatically, so using =& in this
   context is deprecated and produces an E_DEPRECATED message in PHP 5.3 and
   later, and an E_STRICT message in earlier versions. (Technically, the
   difference is that, in PHP 5, object variables, much like resources, are a
   mere pointer to the actual object data, so these object references are not
   "references" in the same sense used before (aliases). For more
   information, see Objects and references.)

   Warning

   If you assign a reference to a variable declared global inside a function,
   the reference will be visible only inside the function. You can avoid this
   by using the $GLOBALS array.

   Example #2 Referencing global variables inside functions

   
   Think about global $var; as a shortcut to $var =& $GLOBALS['var'];. Thus
   assigning another reference to $var only changes the local variable's
   reference.

     Note:

     If you assign a value to a variable with references in a foreach
     statement, the references are modified too.

     Example #3 References and foreach statement

     

   While not being strictly an assignment by reference, expressions created
   with the language construct array() can also behave as such by prefixing &
   to the array element to add. Example:
   

   Note, however, that references inside arrays are potentially dangerous.
   Doing a normal (not by reference) assignment with a reference on the right
   side does not turn the left side into a reference, but references inside
   arrays are preserved in these normal assignments. This also applies to
   function calls where the array is passed by value. Example:
   
   In other words, the reference behavior of arrays is defined in an
   element-by-element basis; the reference behavior of individual elements is
   dissociated from the reference status of the array container.

  Pass By Reference

   The second thing references do is to pass variables by reference. This is
   done by making a local variable in a function and a variable in the
   calling scope referencing the same content. Example:
   
   will make $a to be 6. This happens because in the function foo the
   variable $var refers to the same content as $a. For more information on
   this, read the passing by reference section.

  Return By Reference

   The third thing references can do is return by reference.

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

What References Are Not

   As said before, references are not pointers. That means, the following
   construct won't do what you expect:
   

   What happens is that $var in foo will be bound with $bar in the caller,
   but then re-bound with $GLOBALS["baz"]. There's no way to bind $bar in the
   calling scope to something else using the reference mechanism, since $bar
   is not available in the function foo (it is represented by $var, but $var
   has only variable contents and not name-to-value binding in the calling
   symbol table). You can use returning references to reference variables
   selected by the function.

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

Passing by Reference

   You can pass a variable by reference to a function so the function can
   modify the variable. The syntax is as follows:
   

     Note: There is no reference sign on a function call - only on function
     definitions. Function definitions alone are enough to correctly pass the
     argument by reference. As of PHP 5.3.0, you will get a warning saying
     that "call-time pass-by-reference" is deprecated when you use & in
     foo(&$a);.

   The following things can be passed by reference:
     * Variables, i.e. foo($a)
     * New statements, i.e. foo(new foobar())
     * References returned from functions, i.e.:
       
       See more about returning by reference.

   No other expressions should be passed by reference, as the result is
   undefined. For example, the following examples of passing by reference are
   invalid:
   
   These requirements are for PHP 4.0.4 and later.

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

Returning References

   Returning by reference is useful when you want to use a function to find
   to which variable a reference should be bound. Do not use
   return-by-reference to increase performance. The engine will automatically
   optimize this on its own. Only return references when you have a valid
   technical reason to do so. To return references, use this syntax:
   value;
       }
   }

   $obj = new foo;
   $myValue = &$obj->getValue(); // $myValue is a reference to $obj->value, which is 42.
   $obj->value = 2;
   echo $myValue;                // prints the new value of $obj->value, i.e. 2.
   ?>
   In this example, the property of the object returned by the getValue
   function would be set, not the copy, as it would be without using
   reference syntax.

     Note: Unlike parameter passing, here you have to use & in both places -
     to indicate that you want to return by reference, not a copy, and to
     indicate that reference binding, rather than usual assignment, should be
     done for $myValue.

     Note: If you try to return a reference from a function with the syntax:
     return ($this->value); this will not work as you are attempting to
     return the result of an expression, and not a variable, by reference.
     You can only return variables by reference from a function - nothing
     else. Since PHP 4.4.0 in the PHP4 branch, and PHP 5.1.0 in the PHP5
     branch, an E_NOTICE error is issued if the code tries to return a
     dynamic expression or a result of the new operator.

   To use the returned reference, you must use reference assigment:
   
   To pass the returned reference to another function expecting a reference
   you can use this syntax:
   

     Note: Note that array_push(&collector(), 'foo'); will not work, it
     results in a fatal error.

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

Unsetting References

   When you unset the reference, you just break the binding between variable
   name and variable content. This does not mean that variable content will
   be destroyed. For example:
   
   won't unset $b, just $a.

   Again, it might be useful to think about this as analogous to the Unix
   unlink call.

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

Spotting References

   Many syntax constructs in PHP are implemented via referencing mechanisms,
   so everything mentioned herein about reference binding also applies to
   these constructs. Some constructs, like passing and returning by
   reference, are mentioned above. Other constructs that use references are:

  global References

   When you declare a variable as global $var you are in fact creating
   reference to a global variable. That means, this is the same as:
   

   This also means that unsetting $var won't unset the global variable.

  $this

   In an object method, $this is always a reference to the caller object.

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

                              Predefined Variables

   PHP provides a large number of predefined variables to all scripts. The
   variables represent everything from external variables to built-in
   environment variables, last error messages to last retrieved headers.

   See also the FAQ titled "How does register_globals affect me?"

     ----------------------------------------------------------------------

                                  Superglobals

   Superglobals - Superglobals are built-in variables that are always
   available in all scopes

  Description

   Several predefined variables in PHP are "superglobals", which means they
   are available in all scopes throughout a script. There is no need to do
   global $variable; to access them within functions or methods.

   These superglobal variables are:
     * $GLOBALS
     * $_SERVER
     * $_GET
     * $_POST
     * $_FILES
     * $_COOKIE
     * $_SESSION
     * $_REQUEST
     * $_ENV

  Changelog

   Version             Description              
   4.1.0   Superglobals were introduced to PHP. 

  Notes

     Note: Variable availability

     By default, all of the superglobals are available but there are
     directives that affect this availability. For further information, refer
     to the documentation for variables_order.

     Note: Dealing with register_globals

     If the deprecated register_globals directive is set to on then the
     variables within will also be made available in the global scope of the
     script. For example, $_POST['foo'] would also exist as $foo.

     For related information, see the FAQ titled "How does register_globals
     affect me?"

     Note: Variable variables

     Superglobals cannot be used as variable variables inside functions or
     class methods.

  See Also

     * variable scope
     * The variables_order directive
     * The filter extension

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

                                    $GLOBALS

   (PHP 4, PHP 5)

   $GLOBALS - References all variables available in global scope

  Description

   An associative array containing references to all variables which are
   currently defined in the global scope of the script. The variable names
   are the keys of the array.

  Examples

   Example #1 $GLOBALS example

   

   The above example will output something similar to:

 $foo in global scope: Example content
 $foo in current scope: local variable

  Notes

     Note:

     This is a 'superglobal', or automatic global, variable. This simply
     means that it is available in all scopes throughout a script. There is
     no need to do global $variable; to access it within functions or
     methods.

     Note: Variable availability

     Unlike all of the other superglobals, $GLOBALS has essentially always
     been available in PHP.

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

                                    $_SERVER

                         $HTTP_SERVER_VARS [deprecated]

   (PHP 4 >= 4.1.0, PHP 5)

   $_SERVER -- $HTTP_SERVER_VARS [deprecated] - Server and execution
   environment information

  Description

   $_SERVER is an array containing information such as headers, paths, and
   script locations. The entries in this array are created by the web server.
   There is no guarantee that every web server will provide any of these;
   servers may omit some, or provide others not listed here. That said, a
   large number of these variables are accounted for in the >> CGI/1.1
   specification, so you should be able to expect those.

   $HTTP_SERVER_VARS contains the same initial information, but is not a
   superglobal. (Note that $HTTP_SERVER_VARS and $_SERVER are different
   variables and that PHP handles them as such)

  Indices

   You may or may not find any of the following elements in $_SERVER. Note
   that few, if any, of these will be available (or indeed have any meaning)
   if running PHP on the command line.

   'PHP_SELF'
           The filename of the currently executing script, relative to the
           document root. For instance, $_SERVER['PHP_SELF'] in a script at
           the address http://example.com/test.php/foo.bar would be
           /test.php/foo.bar. The __FILE__ constant contains the full path
           and filename of the current (i.e. included) file. If PHP is
           running as a command-line processor this variable contains the
           script name since PHP 4.3.0. Previously it was not available.

   'argv'
           Array of arguments passed to the script. When the script is run on
           the command line, this gives C-style access to the command line
           parameters. When called via the GET method, this will contain the
           query string.

   'argc'
           Contains the number of command line parameters passed to the
           script (if run on the command line).

   'GATEWAY_INTERFACE'
           What revision of the CGI specification the server is using; i.e.
           'CGI/1.1'.

   'SERVER_ADDR'
           The IP address of the server under which the current script is
           executing.

   'SERVER_NAME'
           The name of the server host under which the current script is
           executing. If the script is running on a virtual host, this will
           be the value defined for that virtual host.

   'SERVER_SOFTWARE'
           Server identification string, given in the headers when responding
           to requests.

   'SERVER_PROTOCOL'
           Name and revision of the information protocol via which the page
           was requested; i.e. 'HTTP/1.0';

   'REQUEST_METHOD'
           Which request method was used to access the page; i.e. 'GET',
           'HEAD', 'POST', 'PUT'.

             Note:

             PHP script is terminated after sending headers (it means after
             producing any output without output buffering) if the request
             method was HEAD.

   'REQUEST_TIME'
           The timestamp of the start of the request. Available since PHP
           5.1.0. It is float with microseconds since PHP 5.4.0.

   'QUERY_STRING'
           The query string, if any, via which the page was accessed.

   'DOCUMENT_ROOT'
           The document root directory under which the current script is
           executing, as defined in the server's configuration file.

   'HTTP_ACCEPT'
           Contents of the Accept: header from the current request, if there
           is one.

   'HTTP_ACCEPT_CHARSET'
           Contents of the Accept-Charset: header from the current request,
           if there is one. Example: 'iso-8859-1,*,utf-8'.

   'HTTP_ACCEPT_ENCODING'
           Contents of the Accept-Encoding: header from the current request,
           if there is one. Example: 'gzip'.

   'HTTP_ACCEPT_LANGUAGE'
           Contents of the Accept-Language: header from the current request,
           if there is one. Example: 'en'.

   'HTTP_CONNECTION'
           Contents of the Connection: header from the current request, if
           there is one. Example: 'Keep-Alive'.

   'HTTP_HOST'
           Contents of the Host: header from the current request, if there is
           one.

   'HTTP_REFERER'
           The address of the page (if any) which referred the user agent to
           the current page. This is set by the user agent. Not all user
           agents will set this, and some provide the ability to modify
           HTTP_REFERER as a feature. In short, it cannot really be trusted.

   'HTTP_USER_AGENT'
           Contents of the User-Agent: header from the current request, if
           there is one. This is a string denoting the user agent being which
           is accessing the page. A typical example is: Mozilla/4.5 [en]
           (X11; U; Linux 2.2.9 i586). Among other things, you can use this
           value with get_browser() to tailor your page's output to the
           capabilities of the user agent.

   'HTTPS'
           Set to a non-empty value if the script was queried through the
           HTTPS protocol.

             Note: Note that when using ISAPI with IIS, the value will be off
             if the request was not made through the HTTPS protocol.

   'REMOTE_ADDR'
           The IP address from which the user is viewing the current page.

   'REMOTE_HOST'
           The Host name from which the user is viewing the current page. The
           reverse dns lookup is based off the REMOTE_ADDR of the user.

             Note: Your web server must be configured to create this
             variable. For example in Apache you'll need HostnameLookups On
             inside httpd.conf for it to exist. See also gethostbyaddr().

   'REMOTE_PORT'
           The port being used on the user's machine to communicate with the
           web server.

   'SCRIPT_FILENAME'

           The absolute pathname of the currently executing script.

             Note:

             If a script is executed with the CLI, as a relative path, such
             as file.php or ../file.php, $_SERVER['SCRIPT_FILENAME'] will
             contain the relative path specified by the user.

   'SERVER_ADMIN'
           The value given to the SERVER_ADMIN (for Apache) directive in the
           web server configuration file. If the script is running on a
           virtual host, this will be the value defined for that virtual
           host.

   'SERVER_PORT'
           The port on the server machine being used by the web server for
           communication. For default setups, this will be '80'; using SSL,
           for instance, will change this to whatever your defined secure
           HTTP port is.

   'SERVER_SIGNATURE'
           String containing the server version and virtual host name which
           are added to server-generated pages, if enabled.

   'PATH_TRANSLATED'
           Filesystem- (not document root-) based path to the current script,
           after the server has done any virtual-to-real mapping.

             Note: As of PHP 4.3.2, PATH_TRANSLATED is no longer set
             implicitly under the Apache 2 SAPI in contrast to the situation
             in Apache 1, where it's set to the same value as the
             SCRIPT_FILENAME server variable when it's not populated by
             Apache. This change was made to comply with the CGI
             specification that PATH_TRANSLATED should only exist if
             PATH_INFO is defined. Apache 2 users may use AcceptPathInfo = On
             inside httpd.conf to define PATH_INFO.

   'SCRIPT_NAME'
           Contains the current script's path. This is useful for pages which
           need to point to themselves. The __FILE__ constant contains the
           full path and filename of the current (i.e. included) file.

   'REQUEST_URI'
           The URI which was given in order to access this page; for
           instance, '/index.html'.

   'PHP_AUTH_DIGEST'
           When doing Digest HTTP authentication this variable is set to the
           'Authorization' header sent by the client (which you should then
           use to make the appropriate validation).

   'PHP_AUTH_USER'
           When doing HTTP authentication this variable is set to the
           username provided by the user.

   'PHP_AUTH_PW'
           When doing HTTP authentication this variable is set to the
           password provided by the user.

   'AUTH_TYPE'
           When doing HTTP authenticated this variable is set to the
           authentication type.

   'PATH_INFO'
           Contains any client-provided pathname information trailing the
           actual script filename but preceding the query string, if
           available. For instance, if the current script was accessed via
           the URL
           http://www.example.com/php/path_info.php/some/stuff?foo=bar, then
           $_SERVER['PATH_INFO'] would contain /some/stuff.

   'ORIG_PATH_INFO'
           Original version of 'PATH_INFO' before processed by PHP.

  Changelog

   Version                      Description                       
   4.1.0   Introduced $_SERVER that deprecated $HTTP_SERVER_VARS. 

  Examples

   Example #1 $_SERVER example

   

   The above example will output something similar to:

 www.example.com

  Notes

     Note:

     This is a 'superglobal', or automatic global, variable. This simply
     means that it is available in all scopes throughout a script. There is
     no need to do global $variable; to access it within functions or
     methods.

  See Also

     * The filter extension

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

                                     $_GET

                          $HTTP_GET_VARS [deprecated]

   (PHP 4 >= 4.1.0, PHP 5)

   $_GET -- $HTTP_GET_VARS [deprecated] - HTTP GET variables

  Description

   An associative array of variables passed to the current script via the URL
   parameters.

   $HTTP_GET_VARS contains the same initial information, but is not a
   superglobal. (Note that $HTTP_GET_VARS and $_GET are different variables
   and that PHP handles them as such)

  Changelog

   Version                   Description                    
   4.1.0   Introduced $_GET that deprecated $HTTP_GET_VARS. 

  Examples

   Example #1 $_GET example

   

   Assuming the user entered http://example.com/?name=Hannes

   The above example will output something similar to:

 Hello Hannes!

  Notes

     Note:

     This is a 'superglobal', or automatic global, variable. This simply
     means that it is available in all scopes throughout a script. There is
     no need to do global $variable; to access it within functions or
     methods.

     Note:

     The GET variables are passed through urldecode().

  See Also

     * Handling external variables
     * The filter extension

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

                                     $_POST

                          $HTTP_POST_VARS [deprecated]

   (PHP 4 >= 4.1.0, PHP 5)

   $_POST -- $HTTP_POST_VARS [deprecated] - HTTP POST variables

  Description

   An associative array of variables passed to the current script via the
   HTTP POST method.

   $HTTP_POST_VARS contains the same initial information, but is not a
   superglobal. (Note that $HTTP_POST_VARS and $_POST are different variables
   and that PHP handles them as such)

  Changelog

   Version                    Description                     
   4.1.0   Introduced $_POST that deprecated $HTTP_POST_VARS. 

  Examples

   Example #1 $_POST example

   

   Assuming the user POSTed name=Hannes

   The above example will output something similar to:

 Hello Hannes!

  Notes

     Note:

     This is a 'superglobal', or automatic global, variable. This simply
     means that it is available in all scopes throughout a script. There is
     no need to do global $variable; to access it within functions or
     methods.

  See Also

     * Handling external variables
     * The filter extension

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

                                    $_FILES

                         $HTTP_POST_FILES [deprecated]

   (PHP 4 >= 4.1.0, PHP 5)

   $_FILES -- $HTTP_POST_FILES [deprecated] - HTTP File Upload variables

  Description

   An associative array of items uploaded to the current script via the HTTP
   POST method.

   $HTTP_POST_FILES contains the same initial information, but is not a
   superglobal. (Note that $HTTP_POST_FILES and $_FILES are different
   variables and that PHP handles them as such)

  Changelog

   Version                     Description                      
   4.1.0   Introduced $_FILES that deprecated $HTTP_POST_FILES. 

  Notes

     Note:

     This is a 'superglobal', or automatic global, variable. This simply
     means that it is available in all scopes throughout a script. There is
     no need to do global $variable; to access it within functions or
     methods.

  See Also

     * move_uploaded_file() - Moves an uploaded file to a new location
     * Handling File Uploads

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

                                   $_REQUEST

   (PHP 4 >= 4.1.0, PHP 5)

   $_REQUEST - HTTP Request variables

  Description

   An associative array that by default contains the contents of $_GET,
   $_POST and $_COOKIE.

  Changelog

   Version                            Description                             
   5.3.0   Introduced request_order. This directive affects the contents of   
           $_REQUEST.                                                         
   4.3.0   $_FILES information was removed from $_REQUEST.                    
   4.1.0   Introduced $_REQUEST.                                              

  Notes

     Note:

     This is a 'superglobal', or automatic global, variable. This simply
     means that it is available in all scopes throughout a script. There is
     no need to do global $variable; to access it within functions or
     methods.

     Note:

     When running on the command line , this will not include the argv and
     argc entries; these are present in the $_SERVER array.

     Note:

     The variables in $_REQUEST are provided to the script via the GET, POST,
     and COOKIE input mechanisms and therefore could be modified by the
     remote user and cannot be trusted. The presence and order of variables
     listed in this array is defined according to the PHP variables_order
     configuration directive.

  See Also

     * import_request_variables() - Import GET/POST/Cookie variables into the
       global scope
     * Handling external variables
     * The filter extension

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

                                   $_SESSION

                        $HTTP_SESSION_VARS [deprecated]

   (PHP 4 >= 4.1.0, PHP 5)

   $_SESSION -- $HTTP_SESSION_VARS [deprecated] - Session variables

  Description

   An associative array containing session variables available to the current
   script. See the Session functions documentation for more information on
   how this is used.

   $HTTP_SESSION_VARS contains the same initial information, but is not a
   superglobal. (Note that $HTTP_SESSION_VARS and $_SESSION are different
   variables and that PHP handles them as such)

  Changelog

   Version                       Description                        
   4.1.0   Introduced $_SESSION that deprecated $HTTP_SESSION_VARS. 

  Notes

     Note:

     This is a 'superglobal', or automatic global, variable. This simply
     means that it is available in all scopes throughout a script. There is
     no need to do global $variable; to access it within functions or
     methods.

  See Also

     * session_start() - Initialize session data

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

                                     $_ENV

                          $HTTP_ENV_VARS [deprecated]

   (PHP 4 >= 4.1.0, PHP 5)

   $_ENV -- $HTTP_ENV_VARS [deprecated] - Environment variables

  Description

   An associative array of variables passed to the current script via the
   environment method.

   These variables are imported into PHP's global namespace from the
   environment under which the PHP parser is running. Many are provided by
   the shell under which PHP is running and different systems are likely
   running different kinds of shells, a definitive list is impossible. Please
   see your shell's documentation for a list of defined environment
   variables.

   Other environment variables include the CGI variables, placed there
   regardless of whether PHP is running as a server module or CGI processor.

   $HTTP_ENV_VARS contains the same initial information, but is not a
   superglobal. (Note that $HTTP_ENV_VARS and $_ENV are different variables
   and that PHP handles them as such)

  Changelog

   Version                   Description                    
   4.1.0   Introduced $_ENV that deprecated $HTTP_ENV_VARS. 

  Examples

   Example #1 $_ENV example

   

   Assuming "bjori" executes this script

   The above example will output something similar to:

 My username is bjori!

  Notes

     Note:

     This is a 'superglobal', or automatic global, variable. This simply
     means that it is available in all scopes throughout a script. There is
     no need to do global $variable; to access it within functions or
     methods.

  See Also

     * getenv() - Gets the value of an environment variable
     * The filter extension

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

                                    $_COOKIE

                         $HTTP_COOKIE_VARS [deprecated]

   (PHP 4 >= 4.1.0, PHP 5)

   $_COOKIE -- $HTTP_COOKIE_VARS [deprecated] - HTTP Cookies

  Description

   An associative array of variables passed to the current script via HTTP
   Cookies.

   $HTTP_COOKIE_VARS contains the same initial information, but is not a
   superglobal. (Note that $HTTP_COOKIE_VARS and $_COOKIE are different
   variables and that PHP handles them as such)

  Changelog

   Version                      Description                       
   4.1.0   Introduced $_COOKIE that deprecated $HTTP_COOKIE_VARS. 

  Examples

   Example #1 $_COOKIE example

   

   Assuming the "name" cookie has been set earlier

   The above example will output something similar to:

 Hello Hannes!

  Notes

     Note:

     This is a 'superglobal', or automatic global, variable. This simply
     means that it is available in all scopes throughout a script. There is
     no need to do global $variable; to access it within functions or
     methods.

  See Also

     * setcookie() - Send a cookie
     * Handling external variables
     * The filter extension

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

                                 $php_errormsg

   (PHP 4, PHP 5)

   $php_errormsg - The previous error message

  Description

   $php_errormsg is a variable containing the text of the last error message
   generated by PHP. This variable will only be available within the scope in
   which the error occurred, and only if the track_errors configuration
   option is turned on (it defaults to off).

     Note: This variable is only available when track_errors is enabled in
     php.ini.

   Warning

   If a user defined error handler (set_error_handler()) is set $php_errormsg
   is only set if the error handler returns FALSE

  Examples

   Example #1 $php_errormsg example

   

   The above example will output something similar to:

 Wrong parameter count for strpos()

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

                              $HTTP_RAW_POST_DATA

   (PHP 4, PHP 5)

   $HTTP_RAW_POST_DATA - Raw POST data

  Description

   $HTTP_RAW_POST_DATA contains the raw POST data. See
   always_populate_raw_post_data

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

                             $http_response_header

   (PHP 4 >= 4.0.4, PHP 5)

   $http_response_header - HTTP response headers

  Description

   The $http_response_header array is similar to the get_headers() function.
   When using the HTTP wrapper, $http_response_header will be populated with
   the HTTP response headers. $http_response_header will be created in the
   local scope.

  Examples

   Example #1 $http_response_header example

   

   The above example will output something similar to:

 array(9) {
   [0]=>
   string(15) "HTTP/1.1 200 OK"
   [1]=>
   string(35) "Date: Sat, 12 Apr 2008 17:30:38 GMT"
   [2]=>
   string(29) "Server: Apache/2.2.3 (CentOS)"
   [3]=>
   string(44) "Last-Modified: Tue, 15 Nov 2005 13:24:10 GMT"
   [4]=>
   string(27) "ETag: "280100-1b6-80bfd280""
   [5]=>
   string(20) "Accept-Ranges: bytes"
   [6]=>
   string(19) "Content-Length: 438"
   [7]=>
   string(17) "Connection: close"
   [8]=>
   string(38) "Content-Type: text/html; charset=UTF-8"
 }
 NULL

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

                                     $argc

   (PHP 4, PHP 5)

   $argc - The number of arguments passed to script

  Description

   Contains the number of arguments passed to the current script when running
   from the command line.

     Note: The script's filename is always passed as an argument to the
     script, therefore the minimum value of $argc is 1.

     Note: This variable is not available when register_argc_argv is
     disabled.

  Examples

   Example #1 $argc example

   

   When executing the example with: php script.php arg1 arg2 arg3

   The above example will output something similar to:

 int(4)

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

                                     $argv

   (PHP 4, PHP 5)

   $argv - Array of arguments passed to script

  Description

   Contains an array of all the arguments passed to the script when running
   from the command line.

     Note: The first argument $argv[0] is always the name that was used to
     run the script.

     Note: This variable is not available when register_argc_argv is
     disabled.

  Examples

   Example #1 $argv example

   

   When executing the example with: php script.php arg1 arg2 arg3

   The above example will output something similar to:

 array(4) {
   [0]=>
   string(10) "script.php"
   [1]=>
   string(4) "arg1"
   [2]=>
   string(4) "arg2"
   [3]=>
   string(4) "arg3"
 }

  See Also

     * getopt() - Gets options from the command line argument list

     ----------------------------------------------------------------------

Table of Contents

     * Superglobals - Superglobals are built-in variables that are always
       available in all scopes
     * $GLOBALS - References all variables available in global scope
     * $_SERVER - Server and execution environment information
     * $_GET - HTTP GET variables
     * $_POST - HTTP POST variables
     * $_FILES - HTTP File Upload variables
     * $_REQUEST - HTTP Request variables
     * $_SESSION - Session variables
     * $_ENV - Environment variables
     * $_COOKIE - HTTP Cookies
     * $php_errormsg - The previous error message
     * $HTTP_RAW_POST_DATA - Raw POST data
     * $http_response_header - HTTP response headers
     * $argc - The number of arguments passed to script
     * $argv - Array of arguments passed to script

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

                             Predefined Exceptions

Table of Contents

     * Exception
     * ErrorException

   See also the SPL Exceptions

     ----------------------------------------------------------------------

                                   Exception

Introduction

   Exception is the base class for all Exceptions.

Class synopsis

   Exception {
   /* Properties */
   protected string $Exception->message ;
   protected int $code ;
   protected string $file ;
   protected int $line ;
   /* Methods */
   public Exception::__construct ([ string $message = "" [, int $code = 0 [,
   Exception $previous = NULL ]]] )
   final public string Exception::getMessage ( void )
   final public Exception Exception::getPrevious ( void )
   final public mixed Exception::getCode ( void )
   final public string Exception::getFile ( void )
   final public int Exception::getLine ( void )
   final public array Exception::getTrace ( void )
   final public string Exception::getTraceAsString ( void )
   public string Exception::__toString ( void )
   final private void Exception::__clone ( void )
   }

Properties

   message

           The exception message

   code

           The Exception code

   file

           The filename where the exception was thrown

   line

           The line where the exception was thrown

     ----------------------------------------------------------------------

                             Exception::__construct

   (PHP 5 >= 5.1.0)

   Exception::__construct - Construct the exception

  Description

   public Exception::__construct() ([ string $message = "" [, int $code = 0
   [, Exception $previous = NULL ]]] )

   Constructs the Exception.

  Parameters

   message

           The Exception message to throw.

   code

           The Exception code.

   previous

           The previous exception used for the exception chaining.

  Changelog

   Version            Description            
   5.3.0   The previous parameter was added. 

  Notes

     Note:

     The message is NOT binary safe.

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

                             Exception::getMessage

   (PHP 5 >= 5.1.0)

   Exception::getMessage - Gets the Exception message

  Description

   final public string Exception::getMessage ( void )

   Returns the Exception message.

  Parameters

   This function has no parameters.

  Return Values

   Returns the Exception message as a string.

  Examples

   Example #1 Exception::getMessage() example

   getMessage();
   }
   ?>

   The above example will output something similar to:

 Some error message

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

                             Exception::getPrevious

   (PHP 5 >= 5.3.0)

   Exception::getPrevious - Returns previous Exception

  Description

   final public Exception Exception::getPrevious ( void )

   Returns previous Exception (the third parameter of
   Exception::__construct()).

  Parameters

   This function has no parameters.

  Return Values

   Returns the previous Exception if available or NULL otherwise.

  Examples

   Example #1 Exception::getPrevious() example

   Looping over, and printing out, exception trace.

   getFile(), $e->getLine(), $e->getMessage(), $e->getCode(), get_class($e));
       } while($e = $e->getPrevious());
   }
   ?>

   The above example will output something similar to:

 /home/bjori/ex.php:8 Something happend (911) [MyCustomException]
 /home/bjori/ex.php:6 You are doing it wrong! (112) [InvalidArgumentException]

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

                               Exception::getCode

   (PHP 5 >= 5.1.0)

   Exception::getCode - Gets the Exception code

  Description

   final public mixed Exception::getCode ( void )

   Returns the Exception code.

  Parameters

   This function has no parameters.

  Return Values

   Returns the exception code as integer in Exception but possibly as other
   type in Exception descendants (for example as string in PDOException).

  Examples

   Example #1 Exception::getCode() example

   getCode();
   }
   ?>

   The above example will output something similar to:

 The exception code is: 30

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

                               Exception::getFile

   (PHP 5 >= 5.1.0)

   Exception::getFile - Gets the file in which the exception occurred

  Description

   final public string Exception::getFile ( void )

   Get the name of the file the exception was created.

  Parameters

   This function has no parameters.

  Return Values

   Returns the filename in which the exception was created.

  Examples

   Example #1 Exception::getFile() example

   getFile();
   }
   ?>

   The above example will output something similar to:

 /home/bjori/tmp/ex.php

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

                               Exception::getLine

   (PHP 5 >= 5.1.0)

   Exception::getLine - Gets the line in which the exception occurred

  Description

   final public int Exception::getLine ( void )

   Get line number where the exception was created.

  Parameters

   This function has no parameters.

  Return Values

   Returns the line number where the exception was created.

  Examples

   Example #1 Exception::getLine() example

   getLine();
   }
   ?>

   The above example will output something similar to:

 The exception was created on line: 3

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

                              Exception::getTrace

   (PHP 5 >= 5.1.0)

   Exception::getTrace - Gets the stack trace

  Description

   final public array Exception::getTrace ( void )

   Returns the Exception stack trace.

  Parameters

   This function has no parameters.

  Return Values

   Returns the Exception stack trace as an array.

  Examples

   Example #1 Exception::getTrace() example

   getTrace());
   }
   ?>

   The above example will output something similar to:

 array(1) {
   [0]=>
   array(4) {
     ["file"]=>
     string(22) "/home/bjori/tmp/ex.php"
     ["line"]=>
     int(7)
     ["function"]=>
     string(4) "test"
     ["args"]=>
     array(0) {
     }
   }
 }

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

                          Exception::getTraceAsString

   (PHP 5 >= 5.1.0)

   Exception::getTraceAsString - Gets the stack trace as a string

  Description

   final public string Exception::getTraceAsString ( void )

   Returns the Exception stack trace as a string.

  Parameters

   This function has no parameters.

  Return Values

   Returns the Exception stack trace as a string.

  Examples

   Example #1 Exception::getTraceAsString() example

   getTraceAsString();
   }
   ?>

   The above example will output something similar to:

 #0 /home/bjori/tmp/ex.php(7): test()
 #1 {main}

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

                             Exception::__toString

   (PHP 5 >= 5.1.0)

   Exception::__toString - String representation of the exception

  Description

   public string Exception::__toString ( void )

   Returns the string representation of the exception.

  Parameters

   This function has no parameters.

  Return Values

   Returns the string representation of the exception.

  Examples

   Example #1 Exception::__toString() example

   

   The above example will output something similar to:

 exception 'Exception' with message 'Some error message' in /home/bjori/tmp/ex.php:3
 Stack trace:
 #0 {main}

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

                               Exception::__clone

   (PHP 5 >= 5.1.0)

   Exception::__clone - Clone the exception

  Description

   final private void Exception::__clone ( void )

   Tries to clone the Exception, which results in Fatal error.

  Parameters

   This function has no parameters.

  Return Values

   No value is returned.

  Errors/Exceptions

   Exceptions are not clonable.

     ----------------------------------------------------------------------

Table of Contents

     * Exception::__construct - Construct the exception
     * Exception::getMessage - Gets the Exception message
     * Exception::getPrevious - Returns previous Exception
     * Exception::getCode - Gets the Exception code
     * Exception::getFile - Gets the file in which the exception occurred
     * Exception::getLine - Gets the line in which the exception occurred
     * Exception::getTrace - Gets the stack trace
     * Exception::getTraceAsString - Gets the stack trace as a string
     * Exception::__toString - String representation of the exception
     * Exception::__clone - Clone the exception

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

                                 ErrorException

Introduction

   An Error Exception.

Class synopsis

   ErrorException extends Exception {
   /* Properties */
   protected int $ErrorException->severity ;
   /* Methods */
   public ErrorException::__construct ([ string $message [, int $code [, int
   $severity [, string $filename [, int $lineno ]]]]] )
   final public int ErrorException::getSeverity ( void )
   /* Inherited methods */
   final public string Exception::getMessage ( void )
   final public Exception Exception::getPrevious ( void )
   final public mixed Exception::getCode ( void )
   final public string Exception::getFile ( void )
   final public int Exception::getLine ( void )
   final public array Exception::getTrace ( void )
   final public string Exception::getTraceAsString ( void )
   public string Exception::__toString ( void )
   final private void Exception::__clone ( void )
   }

Properties

   severity

           The severity of the exception

Examples

   Example #1 Use set_error_handler() to change error messages into
   ErrorException.

   

   The above example will output something similar to:

 Fatal error: Uncaught exception 'ErrorException' with message 'Wrong parameter count for strpos()' in /home/bjori/tmp/ex.php:8
 Stack trace:
 #0 [internal function]: exception_error_handler(2, 'Wrong parameter...', '/home/bjori/php...', 8, Array)
 #1 /home/bjori/php/cleandocs/test.php(8): strpos()
 #2 {main}
   thrown in /home/bjori/tmp/ex.php on line 8

     ----------------------------------------------------------------------

                          ErrorException::__construct

   (PHP 5 >= 5.1.0)

   ErrorException::__construct - Construct the exception

  Description

   public ErrorException::__construct() ([ string $message [, int $code [,
   int $severity [, string $filename [, int $lineno ]]]]] )

   Constructs the Exception.

  Parameters

   message

           The Exception message to throw.

   code

           The Exception code.

   severity

           The severity level of the exception.

   filename

           The filename where the exception is thrown.

   lineno

           The line number where the exception is thrown.

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

                          ErrorException::getSeverity

   (PHP 5 >= 5.1.0)

   ErrorException::getSeverity - Gets the exception severity

  Description

   final public int ErrorException::getSeverity ( void )

   Returns the severity of the exception.

  Parameters

   This function has no parameters.

  Return Values

   Returns the severity level of the exception.

  Examples

   Example #1 ErrorException::getSeverity() example

   getSeverity();
   }
   ?>

   The above example will output something similar to:

 This exception severity is: 75

     ----------------------------------------------------------------------

Table of Contents

     * ErrorException::__construct - Construct the exception
     * ErrorException::getSeverity - Gets the exception severity

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

                             Predefined Interfaces

Table of Contents

     * Traversable
     * Iterator
     * IteratorAggregate
     * ArrayAccess
     * Serializable

   See also the SPL Interfaces

     ----------------------------------------------------------------------

                           The Traversable interface

Introduction

   Interface to detect if a class is traversable using foreach.

   Abstract base interface that cannot be implemented alone. Instead it must
   be implemented by either IteratorAggregate or Iterator.

     Note:

     Internal (built-in) classes that implement this interface can be used in
     a foreach construct and do not need to implement IteratorAggregate or
     Iterator.

     Note:

     This is an internal engine interface which cannot be implemented in PHP
     scripts. Either IteratorAggregate or Iterator must be used instead.

Interface synopsis

   Traversable {
   }

   This interface has no methods, its only purpose is to be the base
   interface for all traversable classes.

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

                             The Iterator interface

Introduction

   Interface for external iterators or objects that can be iterated
   themselves internally.

Interface synopsis

   Iterator extends Traversable {
   /* Methods */
   abstract public mixed current ( void )
   abstract public scalar key ( void )
   abstract public void next ( void )
   abstract public void rewind ( void )
   abstract public boolean valid ( void )
   }

   Example #1 Basic usage

   This example demonstrates in which order methods are called when using
   foreach with an iterator.

   position = 0;
       }

       function rewind() {
           var_dump(__METHOD__);
           $this->position = 0;
       }

       function current() {
           var_dump(__METHOD__);
           return $this->array[$this->position];
       }

       function key() {
           var_dump(__METHOD__);
           return $this->position;
       }

       function next() {
           var_dump(__METHOD__);
           ++$this->position;
       }

       function valid() {
           var_dump(__METHOD__);
           return isset($this->array[$this->position]);
       }
   }

   $it = new myIterator;

   foreach($it as $key => $value) {
       var_dump($key, $value);
       echo "\n";
   }
   ?>

   The above example will output something similar to:

 string(18) "myIterator::rewind"
 string(17) "myIterator::valid"
 string(19) "myIterator::current"
 string(15) "myIterator::key"
 int(0)
 string(12) "firstelement"

 string(16) "myIterator::next"
 string(17) "myIterator::valid"
 string(19) "myIterator::current"
 string(15) "myIterator::key"
 int(1)
 string(13) "secondelement"

 string(16) "myIterator::next"
 string(17) "myIterator::valid"
 string(19) "myIterator::current"
 string(15) "myIterator::key"
 int(2)
 string(11) "lastelement"

 string(16) "myIterator::next"
 string(17) "myIterator::valid"

     ----------------------------------------------------------------------

                               Iterator::current

   (PHP 5 >= 5.0.0)

   Iterator::current - Return the current element

  Description

   abstract public mixed Iterator::current ( void )

   Returns the current element.

  Parameters

   This function has no parameters.

  Return Values

   Can return any type.

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

                                 Iterator::key

   (PHP 5 >= 5.0.0)

   Iterator::key - Return the key of the current element

  Description

   abstract public scalar Iterator::key ( void )

   Returns the key of the current element.

  Parameters

   This function has no parameters.

  Return Values

   Returns scalar on success, or NULL on failure.

  Errors/Exceptions

   Issues E_NOTICE on failure.

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

                                 Iterator::next

   (PHP 5 >= 5.0.0)

   Iterator::next - Move forward to next element

  Description

   abstract public void Iterator::next ( void )

   Moves the current position to the next element.

     Note:

     This method is called after each foreach loop.

  Parameters

   This function has no parameters.

  Return Values

   Any returned value is ignored.

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

                                Iterator::rewind

   (PHP 5 >= 5.0.0)

   Iterator::rewind - Rewind the Iterator to the first element

  Description

   abstract public void Iterator::rewind ( void )

   Rewinds back to the first element of the Iterator.

     Note:

     This is the first method called when starting a foreach loop. It will
     not be executed after foreach loops.

  Parameters

   This function has no parameters.

  Return Values

   Any returned value is ignored.

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

                                Iterator::valid

   (PHP 5 >= 5.0.0)

   Iterator::valid - Checks if current position is valid

  Description

   abstract public boolean Iterator::valid ( void )

   This method is called after Iterator::rewind() and Iterator::next() to
   check if the current position is valid.

  Parameters

   This function has no parameters.

  Return Values

   The return value will be casted to boolean and then evaluated. Returns
   TRUE on success or FALSE on failure.

     ----------------------------------------------------------------------

Table of Contents

     * Iterator::current - Return the current element
     * Iterator::key - Return the key of the current element
     * Iterator::next - Move forward to next element
     * Iterator::rewind - Rewind the Iterator to the first element
     * Iterator::valid - Checks if current position is valid

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

                        The IteratorAggregate interface

Introduction

   Interface to create an external Iterator.

Interface synopsis

   IteratorAggregate extends Traversable {
   /* Methods */
   abstract public Traversable getIterator ( void )
   }

   Example #1 Basic usage

   property4 = "last property";
       }

       public function getIterator() {
           return new ArrayIterator($this);
       }
   }

   $obj = new myData;

   foreach($obj as $key => $value) {
       var_dump($key, $value);
       echo "\n";
   }
   ?>

   The above example will output something similar to:

 string(9) "property1"
 string(19) "Public property one"

 string(9) "property2"
 string(19) "Public property two"

 string(9) "property3"
 string(21) "Public property three"

 string(9) "property4"
 string(13) "last property"


     ----------------------------------------------------------------------

                         IteratorAggregate::getIterator

   (PHP 5 >= 5.0.0)

   IteratorAggregate::getIterator - Retrieve an external iterator

  Description

   abstract public Traversable IteratorAggregate::getIterator ( void )

   Returns an external iterator.

  Parameters

   This function has no parameters.

  Return Values

   An instance of an object implementing Iterator or Traversable

  Errors/Exceptions

   Throws an Exception on failure.

     ----------------------------------------------------------------------

Table of Contents

     * IteratorAggregate::getIterator - Retrieve an external iterator

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

                           The ArrayAccess interface

Introduction

   Interface to provide accessing objects as arrays.

Interface synopsis

   ArrayAccess {
   /* Methods */
   abstract public boolean offsetExists ( mixed $offset )
   abstract public mixed offsetGet ( mixed $offset )
   abstract public void offsetSet ( mixed $offset , mixed $value )
   abstract public void offsetUnset ( mixed $offset )
   }

   Example #1 Basic usage

   container = array(
               "one"   => 1,
               "two"   => 2,
               "three" => 3,
           );
       }
       public function offsetSet($offset, $value) {
           if (is_null($offset)) {
               $this->container[] = $value;
           } else {
               $this->container[$offset] = $value;
           }
       }
       public function offsetExists($offset) {
           return isset($this->container[$offset]);
       }
       public function offsetUnset($offset) {
           unset($this->container[$offset]);
       }
       public function offsetGet($offset) {
           return isset($this->container[$offset]) ? $this->container[$offset] : null;
       }
   }

   $obj = new obj;

   var_dump(isset($obj["two"]));
   var_dump($obj["two"]);
   unset($obj["two"]);
   var_dump(isset($obj["two"]));
   $obj["two"] = "A value";
   var_dump($obj["two"]);
   $obj[] = 'Append 1';
   $obj[] = 'Append 2';
   $obj[] = 'Append 3';
   print_r($obj);
   ?>

   The above example will output something similar to:

 bool(true)
 int(2)
 bool(false)
 string(7) "A value"
 obj Object
 (
     [container:obj:private] => Array
         (
             [one] => 1
             [three] => 3
             [two] => A value
             [0] => Append 1
             [1] => Append 2
             [2] => Append 3
         )

 )

     ----------------------------------------------------------------------

                           ArrayAccess::offsetExists

   (PHP 5 >= 5.0.0)

   ArrayAccess::offsetExists - Whether a offset exists

  Description

   abstract public boolean ArrayAccess::offsetExists ( mixed $offset )

   Whether or not an offset exists.

   This method is executed when using isset() or empty() on objects
   implementing ArrayAccess.

     Note:

     When using empty() ArrayAccess::offsetGet() will be called and checked
     if empty only if ArrayAccess::offsetExists() returns TRUE.

  Parameters

   offset

           An offset to check for.

  Return Values

   Returns TRUE on success or FALSE on failure.

     Note:

     The return value will be casted to boolean if non-boolean was returned.

  Examples

   Example #1 ArrayAccess::offsetExists() example

   

   The above example will output something similar to:

 Runs obj::offsetExists()
 string(17) "obj::offsetExists"
 bool(true)

 Runs obj::offsetExists() and obj::offsetGet()
 string(17) "obj::offsetExists"
 string(14) "obj::offsetGet"
 bool(false)

 Runs obj::offsetExists(), *not* obj:offsetGet() as there is nothing to get
 string(17) "obj::offsetExists"
 bool(true)

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

                             ArrayAccess::offsetGet

   (PHP 5 >= 5.0.0)

   ArrayAccess::offsetGet - Offset to retrieve

  Description

   abstract public mixed ArrayAccess::offsetGet ( mixed $offset )

   Returns the value at specified offset.

   This method is executed when checking if offset is empty().

  Parameters

   offset

           The offset to retrieve.

  Notes

     Note:

     Starting with PHP 5.3.4, the prototype checks were relaxed and it's
     possible for implementations of this method to return by reference. This
     makes indirect modifications to the overloaded array dimensions of
     ArrayAccess objects possible.

     A direct modification is one that replaces completely the value of the
     array dimension, as in $obj[6] = 7. An indirect modification, on the
     other hand, only changes part of the dimension, or attempts to assign
     the dimension by reference to another variable, as in $obj[6][7] = 7 or
     $var =& $obj[6]. Increments with ++ and decrements with -- are also
     implemented in a way that requires indirect modification.

     While direct modification triggers a call to ArrayAccess::offsetSet(),
     indirect modification triggers a call to ArrayAccess::offsetGet(). In
     that case, the implementation of ArrayAccess::offsetGet() must be able
     to return by reference, otherwise an E_NOTICE message is raised.

  Return Values

   Can return all value types.

  See Also

     * ArrayAccess::offsetExists() - Whether a offset exists

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

                             ArrayAccess::offsetSet

   (PHP 5 >= 5.0.0)

   ArrayAccess::offsetSet - Offset to set

  Description

   abstract public void ArrayAccess::offsetSet ( mixed $offset , mixed $value
   )

   Assigns a value to the specified offset.

  Parameters

   offset

           The offset to assign the value to.

   value

           The value to set.

  Return Values

   No value is returned.

  Notes

     Note:

     The offset parameter will be set to NULL if another value is not
     available, like in the following example.
     

     The above example will output:

 Array
 (
     [0] => first value
     [1] => second value
 )

     Note:

     This function is not called in assignments by reference and otherwise
     indirect changes to array dimensions overloaded with ArrayAccess
     (indirect in the sense they are made not by changing the dimension
     directly, but by changing a sub-dimension or sub-property or assigning
     the array dimension by reference to another variable). Instead,
     ArrayAccess::offsetGet() is called. The operation will only be
     successful if that method returns by reference, which is only possible
     since PHP 5.3.4.

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

                            ArrayAccess::offsetUnset

   (PHP 5 >= 5.0.0)

   ArrayAccess::offsetUnset - Offset to unset

  Description

   abstract public void ArrayAccess::offsetUnset ( mixed $offset )

   Unsets an offset.

     Note:

     This method will not be called when type-casting to (unset)

  Parameters

   offset

           The offset to unset.

  Return Values

   No value is returned.

     ----------------------------------------------------------------------

Table of Contents

     * ArrayAccess::offsetExists - Whether a offset exists
     * ArrayAccess::offsetGet - Offset to retrieve
     * ArrayAccess::offsetSet - Offset to set
     * ArrayAccess::offsetUnset - Offset to unset

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

                           The Serializable interface

Introduction

   Interface for customized serializing.

   Classes that implement this interface no longer support __sleep() and
   __wakeup(). The method serialize is called whenever an instance needs to
   be serialized. This does not invoke __destruct() or has any other side
   effect unless programmed inside the method. When the data is unserialized
   the class is known and the appropriate unserialize() method is called as a
   constructor instead of calling __construct(). If you need to execute the
   standard constructor you may do so in the method.

Interface synopsis

   Serializable {
   /* Methods */
   abstract public string serialize ( void )
   abstract public mixed unserialize ( string $serialized )
   }

   Example #1 Basic usage

   data = "My private data";
       }
       public function serialize() {
           return serialize($this->data);
       }
       public function unserialize($data) {
           $this->data = unserialize($data);
       }
       public function getData() {
           return $this->data;
       }
   }

   $obj = new obj;
   $ser = serialize($obj);

   var_dump($ser);

   $newobj = unserialize($ser);

   var_dump($newobj->getData());
   ?>

   The above example will output something similar to:

 string(38) "C:3:"obj":23:{s:15:"My private data";}"
 string(15) "My private data"

     ----------------------------------------------------------------------

                            Serializable::serialize

   (PHP 5 >= 5.1.0)

   Serializable::serialize - String representation of object

  Description

   abstract public string Serializable::serialize ( void )

   Should return the string representation of the object.

     Note:

     This method acts as the destructor of the object. The __destruct()
     method will not be called after this method.

  Parameters

   This function has no parameters.

  Return Values

   Returns the string representation of the object or NULL

  Errors/Exceptions

   Throws Exception when returning other types then strings and NULL

  See Also

     * __sleep()

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

                           Serializable::unserialize

   (PHP 5 >= 5.1.0)

   Serializable::unserialize - Constructs the object

  Description

   abstract public mixed Serializable::unserialize ( string $serialized )

   Called during unserialization of the object.

     Note:

     This method acts as the constructor of the object. The __construct()
     method will not be called after this method.

  Parameters

   serialized

           The string representation of the object.

  Return Values

   Returns the original value unserialized.

  See Also

     * __wakeup()

     ----------------------------------------------------------------------

Table of Contents

     * Serializable::serialize - String representation of object
     * Serializable::unserialize - Constructs the object

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

                         Context options and parameters

   PHP offers various context options and parameters which can be used with
   all filesystem and stream wrappers. The context is created with
   stream_context_create(). Options are set with stream_context_set_option()
   and parameters with stream_context_set_params().

     ----------------------------------------------------------------------

                             Socket context options

   Socket context options - Socket context option listing

  Description

   Socket context options are available for all wrappers that work over
   sockets, like tcp, http and ftp.

  Options

   bindto

           Used to specify the IP address (either IPv4 or IPv6) and/or the
           port number that PHP will use to access the network. The syntax is
           ip:port. Setting the IP or the port to 0 will let the system
           choose the IP and/or port.

             Note:

             As FTP creates two socket connections during normal operation,
             the port number cannot be specified using this option.

   backlog

           Used to limit the number of outstanding connections in the
           socket's listen queue.

             Note:

             This is only applicable to stream_socket_server().

  Changelog

   Version  Description   
   5.1.0   Added bindto.  
   5.3.3   Added backlog. 

  Examples

   Example #1 Basic bindto usage example

    array(
           'bindto' => '192.168.0.100:0',
       ),
   );

   // connect to the internet using the '192.168.0.100' IP and port '7000'
   $opts = array(
       'socket' => array(
           'bindto' => '192.168.0.100:7000',
       ),
   );

   // connect to the internet using port '7000'
   $opts = array(
       'socket' => array(
           'bindto' => '0:7000',
       ),
   );

   // create the context...
   $context = stream_context_create($opts);

   // ...and use it to fetch the data
   echo file_get_contents('http://www.example.com', false, $context);

   ?>

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

                              HTTP context options

   HTTP context options - HTTP context option listing

  Description

   Context options for http:// and https:// transports.

  Options

   method string

           GET, POST, or any other HTTP method supported by the remote
           server.

           Defaults to GET.

   header string

           Additional headers to be sent during request. Values in this
           option will override other values (such as User-agent:, Host:, and
           Authentication:).

   user_agent string

           Value to send with User-Agent: header. This value will only be
           used if user-agent is not specified in the header context option
           above.

           By default the user_agent php.ini setting is used.

   content string

           Additional data to be sent after the headers. Typically used with
           POST or PUT requests.

   proxy string

           URI specifying address of proxy server. (e.g.
           tcp://proxy.example.com:5100).

   request_fulluri boolean

           When set to TRUE, the entire URI will be used when constructing
           the request. (i.e. GET http://www.example.com/path/to/file.html
           HTTP/1.0). While this is a non-standard request format, some proxy
           servers require it.

           Defaults to FALSE.

   follow_location integer

           Follow Location: .. redirects.

           Defaults to TRUE.

   max_redirects integer

           The max number of redirects to follow. Value 1 or less means that
           no redirects are followed.

           Defaults to 20.

   protocol_version float

           HTTP protocol version.

           Defaults to 1.0.

             Note:

             PHP prior to 5.3.0 does not implement chunked transfer decoding.
             If this value is set to 1.1 it is your responsibility to be 1.1
             compliant.

   timeout float

           Read timeout in seconds, specified by a float (e.g. 10.5).

           By default the default_socket_timeout php.ini setting is used.

   ignore_errors boolean

           Fetch the content even on failure status codes.

           Defaults to FALSE

  Changelog

   Version                            Description                             
   5.3.4   Added follow_location.                                             
   5.3.0   The protocol_version supports chunked transfer decoding when set   
           to 1.1.                                                            
   5.2.10  Added ignore_errors.                                               
   5.2.10  The header can now be an numerically indexed array.                
   5.2.1   Added timeout.                                                     
   5.1.0   Added HTTPS proxying through HTTP proxies.                         
   5.1.0   Added max_redirects.                                               
   5.1.0   Added protocol_version.                                            

  Examples

   Example #1 Fetch a page and send POST data

    'some content',
           'var2' => 'doh'
       )
   );

   $opts = array('http' =>
       array(
           'method'  => 'POST',
           'header'  => 'Content-type: application/x-www-form-urlencoded',
           'content' => $postdata
       )
   );

   $context  = stream_context_create($opts);

   $result = file_get_contents('http://example.com/submit.php', false, $context);

   ?>

   Example #2 Ignore redirects but fetch headers and content

    array('method' => 'GET',
                                          'max_redirects' => '0',
                                          'ignore_errors' => '1')
          );

   $context = stream_context_create($opts);
   $stream = fopen($url, 'r', false, $context);

   // header information as well as meta data
   // about the stream
   var_dump(stream_get_meta_data($stream));

   // actual data at $url
   var_dump(stream_get_contents($stream));
   fclose($stream);
   ?>

  Notes

     Note: Underlying socket stream context options
     Additional context options may be supported by the underlying transport
     For http:// streams, refer to context options for the tcp:// transport.
     For https:// streams, refer to context options for the ssl:// transport.

     Note: HTTP status line
     When this stream wrapper follows a redirect, the wrapper_data returned
     by stream_get_meta_data() might not necessarily contain the HTTP status
     line that actually applies to the content data at index 0.

 array (
   'wrapper_data' =>
   array (
     0 => 'HTTP/1.0 301 Moved Permantenly',
     1 => 'Cache-Control: no-cache',
     2 => 'Connection: close',
     3 => 'Location: http://example.com/foo.jpg',
     4 => 'HTTP/1.1 200 OK',
     ...

     The first request returned a 301 (permanent redirect), so the stream
     wrapper automatically followed the redirect to get a 200 response (index
     = 4).

  See Also

     * http://
     * Socket context options
     * SSL context options

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

                              FTP context options

   FTP context options - FTP context option listing

  Description

   Context options for ftp:// and ftps:// transports.

  Options

   overwrite boolean

           Allow overwriting of already existing files on remote server.
           Applies to write mode (uploading) only.

           Defaults to FALSE.

   resume_pos integer

           File offset at which to begin transfer. Applies to read mode
           (downloading) only.

           Defaults to 0 (Beginning of File).

   proxy string

           Proxy FTP request via http proxy server. Applies to file read
           operations only. Ex: tcp://squid.example.com:8000.

  Changelog

   Version           Description           
   5.1.0   Added proxy.                    
   5.0.0   Added overwrite and resume_pos. 

  Notes

     Note: Underlying socket stream context options
     Additional context options may be supported by the underlying transport
     For ftp:// streams, refer to context options for the tcp:// transport.
     For ftps:// streams, refer to context options for the ssl:// transport.

  See Also

     * ftp://
     * Socket context options
     * SSL context options

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

                              SSL context options

   SSL context options - SSL context option listing

  Description

   Context options for ssl:// and tls:// transports.

  Options

   verify_peer boolean

           Require verification of SSL certificate used.

           Defaults to FALSE.

   allow_self_signed boolean

           Allow self-signed certificates.

           Defaults to FALSE

   cafile string

           Location of Certificate Authority file on local filesystem which
           should be used with the verify_peer context option to authenticate
           the identity of the remote peer.

   capath string

           If cafile is not specified or if the certificate is not found
           there, the directory pointed to by capath is searched for a
           suitable certificate. capath must be a correctly hashed
           certificate directory.

   local_cert string

           Path to local certificate file on filesystem. It must be a PEM
           encoded file which contains your certificate and private key. It
           can optionally contain the certificate chain of issuers.

   passphrase string

           Passphrase with which your local_cert file was encoded.

   CN_match string

           Common Name we are expecting. PHP will perform limited wildcard
           matching. If the Common Name does not match this, the connection
           attempt will fail.

   verify_depth integer

           Abort if the certificate chain is too deep.

           Defaults to no verification.

   ciphers string

           Sets the list of available ciphers. The format of the string is
           described in >> ciphers(1).

           Defaults to DEFAULT.

   capture_peer_cert boolean

           If set to TRUE a peer_certificate context option will be created
           containing the peer certificate.

   capture_peer_cert_chain boolean

           If set to TRUE a peer_certificate_chain context option will be
           created containing the certificate chain.

   SNI_enabled boolean

           If set to TRUE server name indication will be enabled. Enabling
           SNI allows multiple certificates on the same IP address.

   SNI_server_name string

           If set, then this value will be used as server name for server
           name indication. If this value is not set, then the server name is
           guessed based on the hostname used when opening the stream.

  Changelog

   Version                       Description                        
   5.3.2   Added SNI_enabled and SNI_server_name.                   
   5.0.0   Added capture_peer_cert, capture_peer_chain and ciphers. 

  Notes

     Note: Because ssl:// is the underlying transport for the https:// and
     ftps:// wrappers, any context options which apply to ssl:// also apply
     to https:// and ftps://.

     Note: For SNI (Server Name Indication) to be available, then PHP must be
     compiled with OpenSSL 0.9.8j or greater. Use the
     OPENSSL_TLSEXT_SERVER_NAME to determine whether SNI is supported.

  See Also

     * Socket context options

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

                              CURL context options

   CURL context options - CURL context option listing

  Description

   CURL context options are available when the CURL extension was compiled
   using the --with-curlwrappers configure option.

  Options

   method string

           GET, POST, or any other HTTP method supported by the remote
           server.

           Defaults to GET.

   header string

           Additional headers to be sent during request. Values in this
           option will override other values (such as User-agent:, Host:, and
           Authentication:).

   user_agent string

           Value to send with User-Agent: header.

           By default the user_agent php.ini setting is used.

   content string

           Additional data to be sent after the headers. This option is not
           used for GET or HEAD requests.

   proxy string

           URI specifying address of proxy server. (e.g.
           tcp://proxy.example.com:5100).

   max_redirects integer

           The max number of redirects to follow. Value 1 or less means that
           no redirects are followed.

           Defaults to 20.

   curl_verify_ssl_host boolean

           Verify the host.

           Defaults to FALSE

             Note:

             This option is available for both the http and ftp protocol
             wrappers.

   curl_verify_ssl_peer boolean

           Require verification of SSL certificate used.

           Defaults to FALSE

             Note:

             This option is available for both the http and ftp protocol
             wrappers.

  Examples

   Example #1 Fetch a page and send POST data

    'some content',
           'var2' => 'doh'
       )
   );

   $opts = array('http' =>
       array(
           'method'  => 'POST',
           'header'  => 'Content-type: application/x-www-form-urlencoded',
           'content' => $postdata
       )
   );

   $context  = stream_context_create($opts);

   $result = file_get_contents('http://example.com/submit.php', false, $context);

   ?>

  See Also

     * Socket context options

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

                              Phar context options

   Phar context options - Phar context option listing

  Description

   Context options for phar:// wrapper.

  Options

   compress int

           One of Phar compression constants.

   metadata mixed

           Phar metadata. See Phar::setMetadata().

  See Also

     * phar://
     * Phar stream wrapper

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

                               Context parameters

   Context parameters - Context parameter listing

  Description

   These parameters can be set on a context using the
   stream_context_set_params() function.

  Parameters

   notification callback

           A callback to be called when an event occurs on a stream.

           See stream_notification_callback() for more details.

     ----------------------------------------------------------------------

Table of Contents

     * Socket context options - Socket context option listing
     * HTTP context options - HTTP context option listing
     * FTP context options - FTP context option listing
     * SSL context options - SSL context option listing
     * CURL context options - CURL context option listing
     * Phar context options - Phar context option listing
     * Context parameters - Context parameter listing

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

                        Supported Protocols and Wrappers

   PHP comes with many built-in wrappers for various URL-style protocols for
   use with the filesystem functions such as fopen(), copy(), file_exists()
   and filesize(). In addition to these wrappers, it is possible to register
   custom wrappers using the stream_wrapper_register() function.

     Note: The URL syntax used to describe a wrapper only supports the
     scheme://... syntax. The scheme:/ and scheme: syntaxes are not
     supported.

     ----------------------------------------------------------------------

                                    file://

   file:// - Accessing local filesystem

  Description

   Filesystem is the default wrapper used with PHP and represents the local
   filesystem. When a relative path is specified (a path which does not begin
   with /, \, \\, or a Windows drive letter) the path provided will be
   applied against the current working directory. In many cases this is the
   directory in which the script resides unless it has been changed. Using
   the CLI sapi, this defaults to the directory from which the script was
   called.

   With some functions, such as fopen() and file_get_contents(), include_path
   may be optionally searched for relative paths as well.

  Options

     * /path/to/file.ext
     * relative/path/to/file.ext
     * fileInCwd.ext
     * C:/path/to/winfile.ext
     * C:\path\to\winfile.ext
     * \\smbserver\share\path\to\winfile.ext
     * file:///path/to/file.ext

  Options

                                Wrapper Summary
                  Attribute                Supported 
   Restricted by allow_url_fopen           No        
   Allows Reading                          Yes       
   Allows Writing                          Yes       
   Allows Appending                        Yes       
   Allows Simultaneous Reading and Writing Yes       
   Supports stat()                         Yes       
   Supports unlink()                       Yes       
   Supports rename()                       Yes       
   Supports mkdir()                        Yes       
   Supports rmdir()                        Yes       

  Changelog

   Version  Description   
   5.0.0   Added file://. 

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

                                    http://

                                    https://

   http:// -- https:// - Accessing HTTP(s) URLs

  Description

   Allows read-only access to files/resources via HTTP 1.0, using the HTTP
   GET method. A Host: header is sent with the request to handle name-based
   virtual hosts. If you have configured a user_agent string using your
   php.ini file or the stream context, it will also be included in the
   request.

   The stream allows access to the body of the resource; the headers are
   stored in the $http_response_header variable.

   If it's important to know the URL of the resource where your document came
   from (after all redirects have been processed), you'll need to process the
   series of response headers returned by the stream.

   The from directive will be used for the From: header if set and not
   overwritten by the Context options and parameters.

  Options

     * http://example.com
     * http://example.com/file.php?var1=val1&var2=val2
     * http://user:password@example.com
     * https://example.com
     * https://example.com/file.php?var1=val1&var2=val2
     * https://user:password@example.com

  Options

                                Wrapper Summary
                  Attribute                Supported 
   Restricted by allow_url_fopen           Yes       
   Allows Reading                          Yes       
   Allows Writing                          No        
   Allows Appending                        No        
   Allows Simultaneous Reading and Writing N/A       
   Supports stat()                         No        
   Supports unlink()                       No        
   Supports rename()                       No        
   Supports mkdir()                        No        
   Supports rmdir()                        No        

  Changelog

   Version                            Description                             
   4.3.7   Detect buggy IIS servers to avoid "SSL: Fatal Protocol Error"      
           errors.                                                            
   4.3.0   Added https://.                                                    
   4.0.5   Added support for redirects.                                       

  Examples

   Example #1 Detecting which URL we ended up on after redirects

   

   Example #2 Sending custom headers with an HTTP request

   Custom headers may be sent with an HTTP request by taking advantage of a
   side-effect in the handling of the user_agent INI setting. Set user_agent
   to any valid string (such as the default PHP/version setting) followed by
   a carriage-return/line-feed pair and any additional headers. This method
   works in PHP 4 and all later versions.

   

   Results in the following request being sent:

 GET /index.php HTTP/1.0
 Host: www.example.com
 User-Agent: PHP
 X-MyCustomHeader: Foo

  Notes

     Note: HTTPS is only supported when the openssl extension is enabled.

   HTTP connections are read-only; writing data or copying files to an HTTP
   resource is not supported.

   Sending POST and PUT requests, for example, can be done with the help of
   HTTP Contexts.

  See Also

     * HTTP context options
     * $http_response_header
     * stream_get_meta_data() - Retrieves header/meta data from streams/file
       pointers

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

                                     ftp://

                                    ftps://

   ftp:// -- ftps:// - Accessing FTP(s) URLs

  Description

   Allows read access to existing files and creation of new files via FTP. If
   the server does not support passive mode ftp, the connection will fail.

   You can open files for either reading or writing, but not both
   simultaneously. If the remote file already exists on the ftp server and
   you attempt to open it for writing but have not specified the context
   option overwrite, the connection will fail. If you need to overwrite
   existing files over ftp, specify the overwrite option in the context and
   open the file for writing. Alternatively, you can use the FTP extension.

   If you have set the from directive in php.ini, then this value will be
   sent as the anonymous FTP password.

  Options

     * ftp://example.com/pub/file.txt
     * ftp://user:password@example.com/pub/file.txt
     * ftps://example.com/pub/file.txt
     * ftps://user:password@example.com/pub/file.txt

  Options

                                Wrapper Summary
        Attribute         PHP 4                      PHP 5                    
   Restricted by       Yes         Yes                                        
   allow_url_fopen     
   Allows Reading      Yes         Yes                                        
   Allows Writing      Yes (new    Yes (new files/existing files with         
                       files only) overwrite)                                 
   Allows Appending    No          Yes                                        
   Allows Simultaneous No          No                                         
   Reading and Writing 
                                   As of PHP 5.0.0: filesize(), filetype(),   
   Supports stat()     No          file_exists(), is_file(), and is_dir()     
                                   elements only. As of PHP 5.1.0:            
                                   filemtime().                               
   Supports unlink()   No          Yes                                        
   Supports rename()   No          Yes                                        
   Supports mkdir()    No          Yes                                        
   Supports rmdir()    No          Yes                                        

  Changelog

   Version  Description   
   4.3.0   Added ftps://. 

  Notes

     Note:

     FTPS is only supported when the openssl extension is enabled.

     If the server does not support SSL, then the connection falls back to
     regular unencrypted ftp.

     Note: Appending
     As of PHP 5.0.0 files may be appended via the ftp:// URL wrapper. In
     prior versions, attempting to append to a file via ftp:// will result in
     failure.

  See Also

     * FTP context options

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

                                     php://

   php:// - Accessing various I/O streams

  Description

   PHP provides a number of miscellaneous I/O streams that allow access to
   PHP's own input and output streams, the standard input, output and error
   file descriptors, in-memory and disk-backed temporary file streams, and
   filters that can manipulate other file resources as they are read from and
   written to.

    php://stdin, php://stdout and php://stderr

   php://stdin, php://stdout and php://stderr allow direct access to the
   corresponding input or output stream of the PHP process. The stream
   references a duplicate file descriptor, so if you open php://stdin and
   later close it, you close only your copy of the descriptor-the actual
   stream referenced by STDIN is unaffected. Note that PHP exhibited buggy
   behavior in this regard until PHP 5.2.1. It is recommended that you simply
   use the constants STDIN, STDOUT and STDERR instead of manually opening
   streams using these wrappers.

   php://stdin is read-only, whereas php://stdout and php://stderr are
   write-only.

    php://input

   php://input is a read-only stream that allows you to read raw data from
   the request body. In the case of POST requests, it is preferable to
   $HTTP_RAW_POST_DATA as it does not depend on special php.ini directives.
   Moreover, for those cases where $HTTP_RAW_POST_DATA is not populated by
   default, it is a potentially less memory intensive alternative to
   activating always_populate_raw_post_data. php://input is not available
   with enctype="multipart/form-data".

     Note: A stream opened with php://input can only be read once; the stream
     does not support seek operations. However, depending on the SAPI
     implementation, it may be possible to open another php://input stream
     and restart reading. This is only possible if the request body data has
     been saved. Typically, this is the case for POST requests, but not other
     request methods, such as PUT or PROPFIND.

    php://output

   php://output is a write-only stream that allows you to write to the output
   buffer mechanism in the same way as print() and echo().

    php://fd

   php://fd allows direct access to the given file descriptor. For example,
   php://fd/3 refers to file descriptor 3.

    php://memory and php://temp

   php://memory and php://temp are read-write streams that allow temporary
   data to be stored in a file-like wrapper. The only difference between the
   two is that php://memory will always store its data in memory, whereas
   php://temp will use a temporary file once the amount of data stored hits a
   predefined limit (the default is 2 MB).

   The memory limit of php://temp can be controlled by appending
   /maxmemory:NN, where NN is the maximum amount of data to keep in memory
   before using a temporary file, in bytes.

    php://filter

   php://filter is a kind of meta-wrapper designed to permit the application
   of filters to a stream at the time of opening. This is useful with
   all-in-one file functions such as readfile(), file(), and
   file_get_contents() where there is otherwise no opportunity to apply a
   filter to the stream prior the contents being read.

   The php://filter target takes the following parameters as part of its
   path. Please refer to the examples for specifics on using these
   parameters.

                            php://filter parameters
                 Name                              Description                
   resource= This parameter is required. It specifies  
                                    the stream that you would like to filter. 
   read=                      filter names can be provided here,        
                                    separated by the pipe character (|).      
   write=                     filter names can be provided here,        
                                    separated by the pipe character (|).      
                                    Any filter lists which are not prefixed   
                             both the read and write chains as         
                                    appropriate.                              

  Options

     Wrapper Summary (for php://filter, refer to the summary of the wrapper
                                being filtered)
              Attribute                            Supported                  
   Restricted by allow_url_fopen   No                                         
   Restricted by allow_url_include php://input, php://stdin, php://memory and 
                                   php://temp only.                           
   Allows Reading                  php://stdin, php://input, php://fd,        
                                   php://memory and php://temp only.          
                                   php://stdout, php://stderr, php://output,  
   Allows Writing                  php://fd, php://memory and php://temp      
                                   only.                                      
                                   php://stdout, php://stderr, php://output,  
   Allows Appending                php://fd, php://memory and php://temp      
                                   only. (Equivalent to writing)              
   Allows Simultaneous Reading and php://fd, php://memory and php://temp      
   Writing                         only.                                      
   Supports stat()                 php://memory and php://temp only.          
   Supports unlink()               No                                         
   Supports rename()               No                                         
   Supports mkdir()                No                                         
   Supports rmdir()                No                                         
   Supports stream_select()        php://stdin, php://stdout, php://stderr,   
                                   php://fd and php://temp only.              

  Changelog

   Version               Description               
   5.3.6   php://fd was added.                     
   5.1.0   php://memory and php://temp were added. 
   5.0.0   php://filter was added.                 

  Examples

   Example #1 php://temp/maxmemory

   This optional parameter allows setting the memory limit before php://temp
   starts using a temporary file.

   

   Example #2 php://filter/resource=

   This parameter must be located at the end of your php://filter
   specification and should point to the stream which you want filtered.

   

   Example #3 php://filter/read=

   This parameter takes one or more filternames separated by the pipe
   character |.

   

   Example #4 php://filter/write=

   This parameter takes one or more filternames separated by the pipe
   character |.

   

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

                                    zlib://

                                    bzip2://

                                     zip://

   zlib:// -- bzip2:// -- zip:// - Compression Streams

  Description

   zlib: PHP 4.0.4 - PHP 4.2.3 (systems with fopencookie only)

   compress.zlib:// and compress.bzip2:// PHP 4.3.0 and up

   zlib: works like gzopen(), except that the stream can be used with fread()
   and the other filesystem functions. This is deprecated as of PHP 4.3.0 due
   to ambiguities with filenames containing ':' characters; use
   compress.zlib:// instead.

   compress.zlib:// and compress.bzip2:// are equivalent to gzopen() and
   bzopen() respectively, and operate even on systems that do not support
   fopencookie.

   ZIP extension registers zip: wrapper.

  Options

     * zlib:
     * compress.zlib://
     * compress.bzip2://

  Options

                                Wrapper Summary
              Attribute                            Supported                  
   Restricted by allow_url_fopen   No                                         
   Allows Reading                  Yes                                        
   Allows Writing                  Yes (except zip://)                        
   Allows Appending                Yes (except zip://)                        
   Allows Simultaneous Reading and No                                         
   Writing                         
   Supports stat()                 No, use the normal file:// wrapper to stat 
                                   compressed files.                          
   Supports unlink()               No, use the normal file:// wrapper to      
                                   unlink compressed files.                   
   Supports rename()               No                                         
   Supports mkdir()                No                                         
   Supports rmdir()                No                                         

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

                                    data://

   data:// - Data (RFC 2397)

  Description

   The data: (>> RFC 2397) stream wrapper is available since PHP 5.2.0.

  Options

     * data://text/plain;base64,

  Options

                                Wrapper Summary
                  Attribute                Supported 
   Restricted by allow_url_fopen           No        
   Restricted by allow_url_include         Yes       
   Allows Reading                          Yes       
   Allows Writing                          No        
   Allows Appending                        No        
   Allows Simultaneous Reading and Writing No        
   Supports stat()                         No        
   Supports unlink()                       No        
   Supports rename()                       No        
   Supports mkdir()                        No        
   Supports rmdir()                        No        

  Examples

   Example #1 Print data:// contents

   

   Example #2 Fetch the media type

   

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

                                    glob://

   glob:// - Find pathnames matching pattern

  Description

   The glob: stream wrapper is available since PHP 5.3.0.

  Options

     * glob://

  Options

                                Wrapper Summary
                  Attribute                Supported 
   Restricted by allow_url_fopen           No        
   Restricted by allow_url_include         No        
   Allows Reading                          No        
   Allows Writing                          No        
   Allows Appending                        No        
   Allows Simultaneous Reading and Writing No        
   Supports stat()                         No        
   Supports unlink()                       No        
   Supports rename()                       No        
   Supports mkdir()                        No        
   Supports rmdir()                        No        

  Examples

   Example #1 Basic usage

   getFilename(), $f->getSize()/1024);
   }
   ?>

 tree.php: 1.0K
 findregex.php: 0.6K
 findfile.php: 0.7K
 dba_dump.php: 0.9K
 nocvsdir.php: 1.1K
 phar_from_dir.php: 1.0K
 ini_groups.php: 0.9K
 directorytree.php: 0.9K
 dba_array.php: 1.1K
 class_tree.php: 1.8K

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

                                    phar://

   phar:// - PHP Archive

  Description

   The phar:// stream wrapper is available since PHP 5.3.0. See Phar stream
   wrapper for detailed description.

  Options

     * phar://

  Options

                                Wrapper Summary
                  Attribute                Supported 
   Restricted by allow_url_fopen           No        
   Restricted by allow_url_include         No        
   Allows Reading                          Yes       
   Allows Writing                          Yes       
   Allows Appending                        No        
   Allows Simultaneous Reading and Writing Yes       
   Supports stat()                         Yes       
   Supports unlink()                       Yes       
   Supports rename()                       Yes       
   Supports mkdir()                        Yes       
   Supports rmdir()                        Yes       

  See Also

     * Phar context options

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

                                    ssh2://

   ssh2:// - Secure Shell 2

  Description

   ssh2.shell:// ssh2.exec:// ssh2.tunnel:// ssh2.sftp:// ssh2.scp:// PHP
   4.3.0 and up (PECL)

     Note: This wrapper is not enabled by default
     In order to use the ssh2.*:// wrappers you must install the >> SSH2
     extension available from >> PECL.

   In addition to accepting traditional URI login details, the ssh2 wrappers
   will also reuse open connections by passing the connection resource in the
   host portion of the URL.

  Options

     * ssh2.shell://user:pass@example.com:22/xterm
     * ssh2.exec://user:pass@example.com:22/usr/local/bin/somecmd
     * ssh2.tunnel://user:pass@example.com:22/192.168.0.1:14
     * ssh2.sftp://user:pass@example.com:22/path/to/filename

  Options

                                Wrapper Summary
        Attribute      ssh2.shell ssh2.exec ssh2.tunnel  ssh2.sftp   ssh2.scp 
   Restricted by       Yes        Yes       Yes         Yes          Yes      
   allow_url_fopen     
   Allows Reading      Yes        Yes       Yes         Yes          Yes      
   Allows Writing      Yes        Yes       Yes         Yes          No       
                                                        Yes (When             
   Allows Appending    No         No        No          supported by No
                                                        server)      
   Allows Simultaneous Yes        Yes       Yes         Yes          No       
   Reading and Writing 
   Supports stat()     No         No        No          Yes          No       
   Supports unlink()   No         No        No          Yes          No       
   Supports rename()   No         No        No          Yes          No       
   Supports mkdir()    No         No        No          Yes          No       
   Supports rmdir()    No         No        No          Yes          No       

                                Context options
       Name                      Usage                         Default        
   session      Preconnected ssh2 resource to be reused                       
   sftp         Preallocated sftp resource to be reused                       
   methods      Key exchange, hostkey, cipher,                                
                compression, and MAC methods to use      
   callbacks                                                                  
   username     Username to connect as                                        
   password     Password to use with password                                 
                authentication                           
   pubkey_file  Name of public key file to use for                            
                authentication                           
   privkey_file Name of private key file to use for                           
                authentication                           
   env          Associate array of environment variables                      
                to set                                   
   term         Terminal emulation type to request when                       
                allocating a pty                         
   term_width   Width of terminal requested when                              
                allocating a pty                         
   term_height  Height of terminal requested when                             
                allocating a pty                         
   term_units   Units to use with term_width and         SSH2_TERM_UNIT_CHARS 
                term_height                              

  Examples

   Example #1 Opening a stream from an active connection

   

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

                                     rar://

   rar:// - RAR

  Description

   The wrapper takes the url encoded path to the RAR archive (relative or
   absolute), an optional asterik (*), an optional number sign (#) and an
   optional url encoded entry name, as stored in the archive. Specifying an
   entry name requires the number sign; a leading forward slash in the entry
   name is optional.

   This wrapper can open both files and directories. When opening
   directories, the asterisk sign forces the directory entries names to be
   returned unencoded. If it's not specified, they will be returned url
   encoded - the reason for this is to allow the wrapper to be correctly used
   with built-in functionality like the RecursiveDirectoryIterator in the
   presence of file names that seem like url encoded data.

   If the pound sign and the entry name part are not included, the root of
   the archive will be displayed. This differs from regular directories in
   that the resulting stream will not contain information such as the
   modification time, as the root directory is not stored in an inidivual
   entry in the archive. The usage of the wrapper with
   RecursiveDirectoryIterator requires the number sign to be included in the
   URL when accessing the root, so that the URLs of the children may be
   constructed correctly.

     Note: This wrapper is not enabled by default
     In order to use the rar:// wrapper, you must install the >> rar
     extension available from >> PECL.

   rar:// Available since PECL rar 3.0.0

  Options

     * rar://[*][#[]]

  Options

                                Wrapper Summary
                  Attribute                Supported 
   Restricted by allow_url_fopen           No        
   Restricted by allow_url_include         No        
   Allows Reading                          Yes       
   Allows Writing                          No        
   Allows Appending                        No        
   Allows Simultaneous Reading and Writing No        
   Supports stat()                         Yes       
   Supports unlink()                       No        
   Supports rename()                       No        
   Supports mkdir()                        No        
   Supports rmdir()                        No        

                                Context options
        Name                             Usage                        Default 
                   The password used to encrypt the headers of the            
                   archive, if any. WinRAR will encrypt all the files 
   open_password   with the same password as the headers password      
                   when the later is present, so for archives with    
                   encrypted headers, file_password will be ignored.  
                   The password used to encrypt a file, if any. If            
                   the headers are also encrypted, this option will   
                   be ignored in favor of open_password. The reason   
                   there are two options is to cover the possibility  
   file_password   of supporting archives with different headers and   
                   file passwords, should those archives arise. Note  
                   that if the archive does not have its headers      
                   encrypted, open_password will be ignored and this  
                   option must be used instead.                       
                   A callback to determine the path of missing                
   volume_callback volumes. See RarArchive::open() for more            
                   information.                                       

  Examples

   Example #1 Traversing a RAR archive

   getSubPathName()) .
               (is_dir(parent::current())?" [DIR]":"");
       }
   }

   $f = "rar://" . rawurlencode(dirname(__FILE__)) .
       DIRECTORY_SEPARATOR . 'dirs_and_extra_headers.rar#';

   $it = new RecursiveTreeIterator(new MyRecDirIt($f));

   foreach ($it as $s) {
       echo $s, "\n";
   }
   ?>

   The above example will output something similar to:

 |-allow_everyone_ni [DIR]
 |-file1.txt
 |-file2_*.txt
 |-with_streams.txt
 \-* [DIR]
   |-*\%2Fempty%2E [DIR]
   | \-*\%2Fempty%2E\file7.txt
   |-*\empty [DIR]
   |-*\file3.txt
   |-*\file4_*.txt
   \-*\*_2 [DIR]
     |-*\*_2\file5.txt
     \-*\*_2\file6_*.txt

   Example #2 Opening an encrypted file (header encryption)

   
                   array(
                       'open_password' => 'samplepassword'
                   )
               )
           )
       );
   var_dump(stream_get_contents($stream));
   /* creation and last access date is opt-in in WinRAR, hence most
    * files don't have them */
   var_dump(fstat($stream));
   ?>

   The above example will output something similar to:

 string(26) "Encrypted file 1 contents."
 Array
 (
     [0] => 0
     [1] => 0
     [2] => 33206
     [3] => 1
     [4] => 0
     [5] => 0
     [6] => 0
     [7] => 26
     [8] => 0
     [9] => 1259550052
     [10] => 0
     [11] => -1
     [12] => -1
     [dev] => 0
     [ino] => 0
     [mode] => 33206
     [nlink] => 1
     [uid] => 0
     [gid] => 0
     [rdev] => 0
     [size] => 26
     [atime] => 0
     [mtime] => 1259550052
     [ctime] => 0
     [blksize] => -1
     [blocks] => -1
 )

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

                                     ogg://

   ogg:// - Audio streams

  Description

   Files opened for reading via the ogg:// wrapper are treated as compressed
   audio encoded using the OGG/Vorbis codec. Similarly, files opened for
   writing or appending via the ogg:// wrapper are writen as compressed audio
   data. stream_get_meta_data(), when used on an OGG/Vorbis file opened for
   reading will return various details about the stream including the vendor
   tag, any included comments, the number of channels, the sampling rate, and
   the encoding rate range described by: bitrate_lower, bitrate_upper,
   bitrate_nominal, and bitrate_window.

   ogg:// PHP 4.3.0 and up (PECL)

     Note: This wrapper is not enabled by default
     In order to use the ogg:// wrapper you must install the >> OGG/Vorbis
     extension available from >> PECL.

  Options

     * ogg://soundfile.ogg
     * ogg:///path/to/soundfile.ogg
     * ogg://http://www.example.com/path/to/soundstream.ogg

  Options

                                Wrapper Summary
                  Attribute                Supported 
   Restricted by allow_url_fopen           No        
   Allows Reading                          Yes       
   Allows Writing                          Yes       
   Allows Appending                        Yes       
   Allows Simultaneous Reading and Writing No        
   Supports stat()                         No        
   Supports unlink()                       No        
   Supports rename()                       No        
   Supports mkdir()                        No        
   Supports rmdir()                        No        

                                Context options
     Name                Usage                    Default            Mode     
            PCM encoding to apply while                                       
            reading, one of:                
            OGGVORBIS_PCM_U8,               
            OGGVORBIS_PCM_S8,               
   pcm_mode OGGVORBIS_PCM_U16_BE,           OGGVORBIS_PCM_S16_LE Read
            OGGVORBIS_PCM_S16_BE,           
            OGGVORBIS_PCM_U16_LE, and       
            OGGVORBIS_PCM_S16_LE. (8 vs 16  
            bit, signed or unsigned, big or 
            little endian)                  
   rate     Sampling rate of input data,    44100                Write/Append 
            expressed in Hz                 
            When given as an integer, the                                     
            fixed bitrate at which to       
   bitrate  encode. (16000 to 131072) When  128000               Write/Append
            given as a float, the variable  
            bitrate quality to use. (-1.0   
            to 1.0)                         
            The number of audio channels to                                   
   channels encode, typically 1 (Mono), or  2                    Write/Append
            2 (Stero). May range as high as 
            16.                             
   comments An array of string values to                         Write/Append 
            encode into the track header.   

  Examples

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

                                   expect://

   expect:// - Process Interaction Streams

  Description

   Streams opened via the expect:// wrapper provide access to process'es
   stdio, stdout and stderr via PTY.

     Note: This wrapper is not enabled by default
     In order to use the expect:// wrapper you must install the >> Expect
     extension available from >> PECL.

   expect:// PHP 4.3.0 and up (PECL)

  Options

     * expect://command

  Options

                                Wrapper Summary
                  Attribute                Supported 
   Restricted by allow_url_fopen           No        
   Allows Reading                          Yes       
   Allows Writing                          Yes       
   Allows Appending                        Yes       
   Allows Simultaneous Reading and Writing No        
   Supports stat()                         No        
   Supports unlink()                       No        
   Supports rename()                       No        
   Supports mkdir()                        No        
   Supports rmdir()                        No        

  Examples

     ----------------------------------------------------------------------

Table of Contents

     * file:// - Accessing local filesystem
     * http:// - Accessing HTTP(s) URLs
     * ftp:// - Accessing FTP(s) URLs
     * php:// - Accessing various I/O streams
     * zlib:// - Compression Streams
     * data:// - Data (RFC 2397)
     * glob:// - Find pathnames matching pattern
     * phar:// - PHP Archive
     * ssh2:// - Secure Shell 2
     * rar:// - RAR
     * ogg:// - Audio streams
     * expect:// - Process Interaction Streams

     ----------------------------------------------------------------------

     * Basic syntax
          * Escaping from HTML
          * Instruction separation
          * Comments
     * Types
          * Introduction
          * Booleans
          * Integers
          * Floating point numbers
          * Strings
          * Arrays
          * Objects
          * Resources
          * NULL
          * Pseudo-types and variables used in this documentation
          * Type Juggling
     * Variables
          * Basics
          * Predefined Variables
          * Variable scope
          * Variable variables
          * Variables From External Sources
     * Constants
          * Syntax
          * Magic constants
     * Expressions
     * Operators
          * Operator Precedence
          * Arithmetic Operators
          * Assignment Operators
          * Bitwise Operators
          * Comparison Operators
          * Error Control Operators
          * Execution Operators
          * Incrementing/Decrementing Operators
          * Logical Operators
          * String Operators
          * Array Operators
          * Type Operators
     * Control Structures
          * Introduction
          * if
          * else
          * elseif/else if
          * Alternative syntax for control structures
          * while
          * do-while
          * for
          * foreach
          * break
          * continue
          * switch
          * declare
          * return
          * require
          * include
          * require_once
          * include_once
          * goto
     * Functions
          * User-defined functions
          * Function arguments
          * Returning values
          * Variable functions
          * Internal (built-in) functions
          * Anonymous functions
     * Classes and Objects
          * Introduction
          * The Basics
          * Properties
          * Class Constants
          * Autoloading Classes
          * Constructors and Destructors
          * Visibility
          * Object Inheritance
          * Scope Resolution Operator (::)
          * Static Keyword
          * Class Abstraction
          * Object Interfaces
          * Overloading
          * Object Iteration
          * Patterns
          * Magic Methods
          * Final Keyword
          * Object Cloning
          * Comparing Objects
          * Type Hinting
          * Late Static Bindings
          * Objects and references
          * Object Serialization
          * OOP Changelog
     * Namespaces
          * Namespaces overview
          * Defining namespaces
          * Declaring sub-namespaces
          * Defining multiple namespaces in the same file
          * Using namespaces: Basics
          * Namespaces and dynamic language features
          * namespace keyword and __NAMESPACE__ constant
          * Using namespaces: Aliasing/Importing
          * Global space
          * Using namespaces: fallback to global function/constant
          * Name resolution rules
          * FAQ: things you need to know about namespaces
     * Exceptions
          * Extending Exceptions
     * References Explained
          * What References Are
          * What References Do
          * What References Are Not
          * Passing by Reference
          * Returning References
          * Unsetting References
          * Spotting References
     * Predefined Variables
          * Superglobals - Superglobals are built-in variables that are
            always available in all scopes
          * $GLOBALS - References all variables available in global scope
          * $_SERVER - Server and execution environment information
          * $_GET - HTTP GET variables
          * $_POST - HTTP POST variables
          * $_FILES - HTTP File Upload variables
          * $_REQUEST - HTTP Request variables
          * $_SESSION - Session variables
          * $_ENV - Environment variables
          * $_COOKIE - HTTP Cookies
          * $php_errormsg - The previous error message
          * $HTTP_RAW_POST_DATA - Raw POST data
          * $http_response_header - HTTP response headers
          * $argc - The number of arguments passed to script
          * $argv - Array of arguments passed to script
     * Predefined Exceptions
          * Exception
          * ErrorException
     * Predefined Interfaces
          * Traversable - The Traversable interface
          * Iterator - The Iterator interface
          * IteratorAggregate - The IteratorAggregate interface
          * ArrayAccess - The ArrayAccess interface
          * Serializable - The Serializable interface
     * Context options and parameters
          * Socket context options - Socket context option listing
          * HTTP context options - HTTP context option listing
          * FTP context options - FTP context option listing
          * SSL context options - SSL context option listing
          * CURL context options - CURL context option listing
          * Phar context options - Phar context option listing
          * Context parameters - Context parameter listing
     * Supported Protocols and Wrappers
          * file:// - Accessing local filesystem
          * http:// - Accessing HTTP(s) URLs
          * ftp:// - Accessing FTP(s) URLs
          * php:// - Accessing various I/O streams
          * zlib:// - Compression Streams
          * data:// - Data (RFC 2397)
          * glob:// - Find pathnames matching pattern
          * phar:// - PHP Archive
          * ssh2:// - Secure Shell 2
          * rar:// - RAR
          * ogg:// - Audio streams
          * expect:// - Process Interaction Streams

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

                                    Security

     ----------------------------------------------------------------------

                                  Introduction

   PHP is a powerful language and the interpreter, whether included in a web
   server as a module or executed as a separate CGI binary, is able to access
   files, execute commands and open network connections on the server. These
   properties make anything run on a web server insecure by default. PHP is
   designed specifically to be a more secure language for writing CGI
   programs than Perl or C, and with correct selection of compile-time and
   runtime configuration options, and proper coding practices, it can give
   you exactly the combination of freedom and security you need.

   As there are many different ways of utilizing PHP, there are many
   configuration options controlling its behaviour. A large selection of
   options guarantees you can use PHP for a lot of purposes, but it also
   means there are combinations of these options and server configurations
   that result in an insecure setup.

   The configuration flexibility of PHP is equally rivalled by the code
   flexibility. PHP can be used to build complete server applications, with
   all the power of a shell user, or it can be used for simple server-side
   includes with little risk in a tightly controlled environment. How you
   build that environment, and how secure it is, is largely up to the PHP
   developer.

   This chapter starts with some general security advice, explains the
   different configuration option combinations and the situations they can be
   safely used, and describes different considerations in coding for
   different levels of security.

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

                             General considerations

   A completely secure system is a virtual impossibility, so an approach
   often used in the security profession is one of balancing risk and
   usability. If every variable submitted by a user required two forms of
   biometric validation (such as a retinal scan and a fingerprint), you would
   have an extremely high level of accountability. It would also take half an
   hour to fill out a fairly complex form, which would tend to encourage
   users to find ways of bypassing the security.

   The best security is often unobtrusive enough to suit the requirements
   without the user being prevented from accomplishing their work, or
   over-burdening the code author with excessive complexity. Indeed, some
   security attacks are merely exploits of this kind of overly built
   security, which tends to erode over time.

   A phrase worth remembering: A system is only as good as the weakest link
   in a chain. If all transactions are heavily logged based on time,
   location, transaction type, etc. but the user is only verified based on a
   single cookie, the validity of tying the users to the transaction log is
   severely weakened.

   When testing, keep in mind that you will not be able to test all
   possibilities for even the simplest of pages. The input you may expect
   will be completely unrelated to the input given by a disgruntled employee,
   a cracker with months of time on their hands, or a housecat walking across
   the keyboard. This is why it's best to look at the code from a logical
   perspective, to discern where unexpected data can be introduced, and then
   follow how it is modified, reduced, or amplified.

   The Internet is filled with people trying to make a name for themselves by
   breaking your code, crashing your site, posting inappropriate content, and
   otherwise making your day interesting. It doesn't matter if you have a
   small or large site, you are a target by simply being online, by having a
   server that can be connected to. Many cracking programs do not discern by
   size, they simply trawl massive IP blocks looking for victims. Try not to
   become one.

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

                            Installed as CGI binary

Table of Contents

     * Possible attacks
     * Case 1: only public files served
     * Case 2: using cgi.force_redirect
     * Case 3: setting doc_root or user_dir
     * Case 4: PHP parser outside of web tree

     ----------------------------------------------------------------------

Possible attacks

   Using PHP as a CGI binary is an option for setups that for some reason do
   not wish to integrate PHP as a module into server software (like Apache),
   or will use PHP with different kinds of CGI wrappers to create safe chroot
   and setuid environments for scripts. This setup usually involves
   installing executable PHP binary to the web server cgi-bin directory. CERT
   advisory >> CA-96.11 recommends against placing any interpreters into
   cgi-bin. Even if the PHP binary can be used as a standalone interpreter,
   PHP is designed to prevent the attacks this setup makes possible:

     * Accessing system files: http://my.host/cgi-bin/php?/etc/passwd The
       query information in a URL after the question mark (?) is passed as
       command line arguments to the interpreter by the CGI interface.
       Usually interpreters open and execute the file specified as the first
       argument on the command line. When invoked as a CGI binary, PHP
       refuses to interpret the command line arguments.
     * Accessing any web document on server:
       http://my.host/cgi-bin/php/secret/doc.html The path information part
       of the URL after the PHP binary name, /secret/doc.html is
       conventionally used to specify the name of the file to be opened and
       interpreted by the CGI program. Usually some web server configuration
       directives (Apache: Action) are used to redirect requests to documents
       like http://my.host/secret/script.php to the PHP interpreter. With
       this setup, the web server first checks the access permissions to the
       directory /secret, and after that creates the redirected request
       http://my.host/cgi-bin/php/secret/script.php. Unfortunately, if the
       request is originally given in this form, no access checks are made by
       web server for file /secret/script.php, but only for the /cgi-bin/php
       file. This way any user able to access /cgi-bin/php is able to access
       any protected document on the web server. In PHP, runtime
       configuration directives cgi.force_redirect, doc_root and user_dir can
       be used to prevent this attack, if the server document tree has any
       directories with access restrictions. See below for full the
       explanation of the different combinations.

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

Case 1: only public files served

   If your server does not have any content that is not restricted by
   password or ip based access control, there is no need for these
   configuration options. If your web server does not allow you to do
   redirects, or the server does not have a way to communicate to the PHP
   binary that the request is a safely redirected request, you can specify
   the option --enable-force-cgi-redirect to the configure script. You still
   have to make sure your PHP scripts do not rely on one or another way of
   calling the script, neither by directly
   http://my.host/cgi-bin/php/dir/script.php nor by redirection
   http://my.host/dir/script.php.

   Redirection can be configured in Apache by using AddHandler and Action
   directives (see below).

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

Case 2: using cgi.force_redirect

   The configuration directive cgi.force_redirect prevents anyone from
   calling PHP directly with a URL like
   http://my.host/cgi-bin/php/secretdir/script.php. Instead, PHP will only
   parse in this mode if it has gone through a web server redirect rule. PHP
   older than 4.2.0 used --enable-force-cgi-redirect compile time option for
   this.

   Usually the redirection in the Apache configuration is done with the
   following directives:

 Action php-script /cgi-bin/php
 AddHandler php-script .php

   This option has only been tested with the Apache web server, and relies on
   Apache to set the non-standard CGI environment variable REDIRECT_STATUS on
   redirected requests. If your web server does not support any way of
   telling if the request is direct or redirected, you cannot use this option
   and you must use one of the other ways of running the CGI version
   documented here.

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

Case 3: setting doc_root or user_dir

   To include active content, like scripts and executables, in the web server
   document directories is sometimes considered an insecure practice. If,
   because of some configuration mistake, the scripts are not executed but
   displayed as regular HTML documents, this may result in leakage of
   intellectual property or security information like passwords. Therefore
   many sysadmins will prefer setting up another directory structure for
   scripts that are accessible only through the PHP CGI, and therefore always
   interpreted and not displayed as such.

   Also if the method for making sure the requests are not redirected, as
   described in the previous section, is not available, it is necessary to
   set up a script doc_root that is different from web document root.

   You can set the PHP script document root by the configuration directive
   doc_root in the configuration file, or you can set the environment
   variable PHP_DOCUMENT_ROOT. If it is set, the CGI version of PHP will
   always construct the file name to open with this doc_root and the path
   information in the request, so you can be sure no script is executed
   outside this directory (except for user_dir below).

   Another option usable here is user_dir. When user_dir is unset, only thing
   controlling the opened file name is doc_root. Opening a URL like
   http://my.host/~user/doc.php does not result in opening a file under users
   home directory, but a file called ~user/doc.php under doc_root (yes, a
   directory name starting with a tilde [~]).

   If user_dir is set to for example public_php, a request like
   http://my.host/~user/doc.php will open a file called doc.php under the
   directory named public_php under the home directory of the user. If the
   home of the user is /home/user, the file executed is
   /home/user/public_php/doc.php.

   user_dir expansion happens regardless of the doc_root setting, so you can
   control the document root and user directory access separately.

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

Case 4: PHP parser outside of web tree

   A very secure option is to put the PHP parser binary somewhere outside of
   the web tree of files. In /usr/local/bin, for example. The only real
   downside to this option is that you will now have to put a line similar
   to:

 #!/usr/local/bin/php

   as the first line of any file containing PHP tags. You will also need to
   make the file executable. That is, treat it exactly as you would treat any
   other CGI script written in Perl or sh or any other common scripting
   language which uses the #! shell-escape mechanism for launching itself.

   To get PHP to handle PATH_INFO and PATH_TRANSLATED information correctly
   with this setup, the PHP parser should be compiled with the
   --enable-discard-path configure option.

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

                         Installed as an Apache module

   When PHP is used as an Apache module it inherits Apache's user permissions
   (typically those of the "nobody" user). This has several impacts on
   security and authorization. For example, if you are using PHP to access a
   database, unless that database has built-in access control, you will have
   to make the database accessible to the "nobody" user. This means a
   malicious script could access and modify the database, even without a
   username and password. It's entirely possible that a web spider could
   stumble across a database administrator's web page, and drop all of your
   databases. You can protect against this with Apache authorization, or you
   can design your own access model using LDAP, .htaccess files, etc. and
   include that code as part of your PHP scripts.

   Often, once security is established to the point where the PHP user (in
   this case, the apache user) has very little risk attached to it, it is
   discovered that PHP is now prevented from writing any files to user
   directories. Or perhaps it has been prevented from accessing or changing
   databases. It has equally been secured from writing good and bad files, or
   entering good and bad database transactions.

   A frequent security mistake made at this point is to allow apache root
   permissions, or to escalate apache's abilities in some other way.

   Escalating the Apache user's permissions to root is extremely dangerous
   and may compromise the entire system, so sudo'ing, chroot'ing, or
   otherwise running as root should not be considered by those who are not
   security professionals.

   There are some simpler solutions. By using open_basedir you can control
   and restrict what directories are allowed to be used for PHP. You can also
   set up apache-only areas, to restrict all web based activity to non-user,
   or non-system, files.

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

                              Filesystem Security

Table of Contents

     * Null bytes related issues

   PHP is subject to the security built into most server systems with respect
   to permissions on a file and directory basis. This allows you to control
   which files in the filesystem may be read. Care should be taken with any
   files which are world readable to ensure that they are safe for reading by
   all users who have access to that filesystem.

   Since PHP was designed to allow user level access to the filesystem, it's
   entirely possible to write a PHP script that will allow you to read system
   files such as /etc/passwd, modify your ethernet connections, send massive
   printer jobs out, etc. This has some obvious implications, in that you
   need to ensure that the files that you read from and write to are the
   appropriate ones.

   Consider the following script, where a user indicates that they'd like to
   delete a file in their home directory. This assumes a situation where a
   PHP web interface is regularly used for file management, so the Apache
   user is allowed to delete files in the user home directories.

   Example #1 Poor variable checking leads to....

   
   Since the username and the filename are postable from a user form, they
   can submit a username and a filename belonging to someone else, and delete
   it even if they're not supposed to be allowed to do so. In this case,
   you'd want to use some other form of authentication. Consider what could
   happen if the variables submitted were "../etc/" and "passwd". The code
   would then effectively read:

   Example #2 ... A filesystem attack

   
   There are two important measures you should take to prevent these issues.
     * Only allow limited permissions to the PHP web user binary.
     * Check all variables which are submitted.
   Here is an improved script:

   Example #3 More secure file name checking

   
   However, even this is not without its flaws. If your authentication system
   allowed users to create their own user logins, and a user chose the login
   "../etc/", the system is once again exposed. For this reason, you may
   prefer to write a more customized check:

   Example #4 More secure file name checking

   

   Depending on your operating system, there are a wide variety of files
   which you should be concerned about, including device entries (/dev/ or
   COM1), configuration files (/etc/ files and the .ini files), well known
   file storage areas (/home/, My Documents), etc. For this reason, it's
   usually easier to create a policy where you forbid everything except for
   what you explicitly allow.

     ----------------------------------------------------------------------

Null bytes related issues

   As PHP uses the underlying C functions for filesystem related operations,
   it may handle null bytes in a quite unexpected way. As null bytes denote
   the end of a string in C, strings containing them won't be considered
   entirely but rather only until a null byte occurs. The following example
   shows a vulnerable code that demonstrates this problem:

   Example #1 Script vulnerable to null bytes

   

   Therefore, any tainted string that is used in a filesystem operation
   should always be validated properly. Here is a better version of the
   previous example:

   Example #2 Correctly validating the input

   

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

                               Database Security

Table of Contents

     * Designing Databases
     * Connecting to Database
     * Encrypted Storage Model
     * SQL Injection

   Nowadays, databases are cardinal components of any web based application
   by enabling websites to provide varying dynamic content. Since very
   sensitive or secret information can be stored in a database, you should
   strongly consider protecting your databases.

   To retrieve or to store any information you need to connect to the
   database, send a legitimate query, fetch the result, and close the
   connection. Nowadays, the commonly used query language in this interaction
   is the Structured Query Language (SQL). See how an attacker can tamper
   with an SQL query.

   As you can surmise, PHP cannot protect your database by itself. The
   following sections aim to be an introduction into the very basics of how
   to access and manipulate databases within PHP scripts.

   Keep in mind this simple rule: defense in depth. The more places you take
   action to increase the protection of your database, the less probability
   of an attacker succeeding in exposing or abusing any stored information.
   Good design of the database schema and the application deals with your
   greatest fears.

     ----------------------------------------------------------------------

Designing Databases

   The first step is always to create the database, unless you want to use
   one from a third party. When a database is created, it is assigned to an
   owner, who executed the creation statement. Usually, only the owner (or a
   superuser) can do anything with the objects in that database, and in order
   to allow other users to use it, privileges must be granted.

   Applications should never connect to the database as its owner or a
   superuser, because these users can execute any query at will, for example,
   modifying the schema (e.g. dropping tables) or deleting its entire
   content.

   You may create different database users for every aspect of your
   application with very limited rights to database objects. The most
   required privileges should be granted only, and avoid that the same user
   can interact with the database in different use cases. This means that if
   intruders gain access to your database using your applications
   credentials, they can only effect as many changes as your application can.

   You are encouraged not to implement all the business logic in the web
   application (i.e. your script), instead do it in the database schema using
   views, triggers or rules. If the system evolves, new ports will be
   intended to open to the database, and you have to re-implement the logic
   in each separate database client. Over and above, triggers can be used to
   transparently and automatically handle fields, which often provides
   insight when debugging problems with your application or tracing back
   transactions.

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

Connecting to Database

   You may want to establish the connections over SSL to encrypt
   client/server communications for increased security, or you can use ssh to
   encrypt the network connection between clients and the database server. If
   either of these is used, then monitoring your traffic and gaining
   information about your database will be difficult for a would-be attacker.

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

Encrypted Storage Model

   SSL/SSH protects data travelling from the client to the server, SSL/SSH
   does not protect the persistent data stored in a database. SSL is an
   on-the-wire protocol.

   Once an attacker gains access to your database directly (bypassing the
   webserver), the stored sensitive data may be exposed or misused, unless
   the information is protected by the database itself. Encrypting the data
   is a good way to mitigate this threat, but very few databases offer this
   type of data encryption.

   The easiest way to work around this problem is to first create your own
   encryption package, and then use it from within your PHP scripts. PHP can
   assist you in this with several extensions, such as Mcrypt and Mhash,
   covering a wide variety of encryption algorithms. The script encrypts the
   data before inserting it into the database, and decrypts it when
   retrieving. See the references for further examples of how encryption
   works.

   In case of truly hidden data, if its raw representation is not needed
   (i.e. not be displayed), hashing may also be taken into consideration. The
   well-known example for the hashing is storing the MD5 hash of a password
   in a database, instead of the password itself. See also crypt() and md5().

   Example #1 Using hashed password field

    0) {
       echo 'Welcome, $username!';
   } else {
       echo 'Authentication failed for $username.';
   }

   ?>

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

SQL Injection

   Many web developers are unaware of how SQL queries can be tampered with,
   and assume that an SQL query is a trusted command. It means that SQL
   queries are able to circumvent access controls, thereby bypassing standard
   authentication and authorization checks, and sometimes SQL queries even
   may allow access to host operating system level commands.

   Direct SQL Command Injection is a technique where an attacker creates or
   alters existing SQL commands to expose hidden data, or to override
   valuable ones, or even to execute dangerous system level commands on the
   database host. This is accomplished by the application taking user input
   and combining it with static parameters to build an SQL query. The
   following examples are based on true stories, unfortunately.

   Owing to the lack of input validation and connecting to the database on
   behalf of a superuser or the one who can create users, the attacker may
   create a superuser in your database.

   Example #1 Splitting the result set into pages ... and making superusers
   (PostgreSQL)

   
   Normal users click on the 'next', 'prev' links where the $offset is
   encoded into the URL. The script expects that the incoming $offset is a
   decimal number. However, what if someone tries to break in by appending a
   urlencode()'d form of the following to the URL

 0;
 insert into pg_shadow(usename,usesysid,usesuper,usecatupd,passwd)
     select 'crack', usesysid, 't','t','crack'
     from pg_shadow where usename='postgres';
 --

   If it happened, then the script would present a superuser access to him.
   Note that 0; is to supply a valid offset to the original query and to
   terminate it.

     Note:

     It is common technique to force the SQL parser to ignore the rest of the
     query written by the developer with -- which is the comment sign in SQL.

   A feasible way to gain passwords is to circumvent your search result
   pages. The only thing the attacker needs to do is to see if there are any
   submitted variables used in SQL statements which are not handled properly.
   These filters can be set commonly in a preceding form to customize WHERE,
   ORDER BY, LIMIT and OFFSET clauses in SELECT statements. If your database
   supports the UNION construct, the attacker may try to append an entire
   query to the original one to list passwords from an arbitrary table. Using
   encrypted password fields is strongly encouraged.

   Example #2 Listing out articles ... and some passwords (any database
   server)

   
   The static part of the query can be combined with another SELECT statement
   which reveals all passwords:

 '
 union select '1', concat(uname||'-'||passwd) as name, '1971-01-01', '0' from usertable;
 --

   If this query (playing with the ' and --) were assigned to one of the
   variables used in $query, the query beast awakened.

   SQL UPDATE's are also susceptible to attack. These queries are also
   threatened by chopping and appending an entirely new query to it. But the
   attacker might fiddle with the SET clause. In this case some schema
   information must be possessed to manipulate the query successfully. This
   can be acquired by examining the form variable names, or just simply brute
   forcing. There are not so many naming conventions for fields storing
   passwords or usernames.

   Example #3 From resetting a password ... to gaining more privileges (any
   database server)

   
   But a malicious user sumbits the value ' or uid like'%admin%'; -- to $uid
   to change the admin's password, or simply sets $pwd to "hehehe',
   admin='yes', trusted=100 " (with a trailing space) to gain more
   privileges. Then, the query will be twisted:
   

   A frightening example how operating system level commands can be accessed
   on some database hosts.

   Example #4 Attacking the database hosts operating system (MSSQL Server)

   
   If attacker submits the value a%' exec master..xp_cmdshell 'net user test
   testpass /ADD' -- to $prod, then the $query will be:
   
   MSSQL Server executes the SQL statements in the batch including a command
   to add a new user to the local accounts database. If this application were
   running as sa and the MSSQLSERVER service is running with sufficient
   privileges, the attacker would now have an account with which to access
   this machine.

     Note:

     Some of the examples above is tied to a specific database server. This
     does not mean that a similar attack is impossible against other
     products. Your database server may be similarly vulnerable in another
     manner.

   A worked example of the issues regarding SQL Injection
   Image courtesy of >> xkcd

  Avoidance Techniques

   While it remains obvious that an attacker must possess at least some
   knowledge of the database architecture in order to conduct a successful
   attack, obtaining this information is often very simple. For example, if
   the database is part of an open source or other publicly-available
   software package with a default installation, this information is
   completely open and available. This information may also be divulged by
   closed-source code - even if it's encoded, obfuscated, or compiled - and
   even by your very own code through the display of error messages. Other
   methods include the user of common table and column names. For example, a
   login form that uses a 'users' table with column names 'id', 'username',
   and 'password'.

   These attacks are mainly based on exploiting the code not being written
   with security in mind. Never trust any kind of input, especially that
   which comes from the client side, even though it comes from a select box,
   a hidden input field or a cookie. The first example shows that such a
   blameless query can cause disasters.

     * Never connect to the database as a superuser or as the database owner.
       Use always customized users with very limited privileges.
     * Check if the given input has the expected data type. PHP has a wide
       range of input validating functions, from the simplest ones found in
       Variable Functions and in Character Type Functions (e.g. is_numeric(),
       ctype_digit() respectively) and onwards to the Perl compatible Regular
       Expressions support.
     * If the application waits for numerical input, consider verifying data
       with is_numeric(), or silently change its type using settype(), or use
       its numeric representation by sprintf().

       Example #5 A more secure way to compose a query for paging

       

     * Quote each non numeric user supplied value that is passed to the
       database with the database-specific string escape function (e.g.
       mysql_real_escape_string(), sqlite_escape_string(), etc.). If a
       database-specific string escape mechanism is not available, the
       addslashes() and str_replace() functions may be useful (depending on
       database type). See the first example. As the example shows, adding
       quotes to the static part of the query is not enough, making this
       query easily crackable.
     * Do not print out any database specific information, especially about
       the schema, by fair means or foul. See also Error Reporting and Error
       Handling and Logging Functions.
     * You may use stored procedures and previously defined cursors to
       abstract data access so that users do not directly access tables or
       views, but this solution has another impacts.

   Besides these, you benefit from logging queries either within your script
   or by the database itself, if it supports logging. Obviously, the logging
   is unable to prevent any harmful attempt, but it can be helpful to trace
   back which application has been circumvented. The log is not useful by
   itself, but through the information it contains. More detail is generally
   better than less.

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

     ----------------------------------------------------------------------

                                Error Reporting

   With PHP security, there are two sides to error reporting. One is
   beneficial to increasing security, the other is detrimental.

   A standard attack tactic involves profiling a system by feeding it
   improper data, and checking for the kinds, and contexts, of the errors
   which are returned. This allows the system cracker to probe for
   information about the server, to determine possible weaknesses. For
   example, if an attacker had gleaned information about a page based on a
   prior form submission, they may attempt to override variables, or modify
   them:

   Example #1 Attacking Variables with a custom HTML page

 
The PHP errors which are normally returned can be quite helpful to a developer who is trying to debug a script, indicating such things as the function or file that failed, the PHP file it failed in, and the line number which the failure occurred in. This is all information that can be exploited. It is not uncommon for a php developer to use show_source(), highlight_string(), or highlight_file() as a debugging measure, but in a live site, this can expose hidden variables, unchecked syntax, and other dangerous information. Especially dangerous is running code from known sources with built-in debugging handlers, or using common debugging techniques. If the attacker can determine what general technique you are using, they may try to brute-force a page, by sending various common debugging strings: Example #2 Exploiting common debugging variables
Regardless of the method of error handling, the ability to probe a system for errors leads to providing an attacker with more information. For example, the very style of a generic PHP error indicates a system is running PHP. If the attacker was looking at an .html page, and wanted to probe for the back-end (to look for known weaknesses in the system), by feeding it the wrong data they may be able to determine that a system was built with PHP. A function error can indicate whether a system may be running a specific database engine, or give clues as to how a web page or programmed or designed. This allows for deeper investigation into open database ports, or to look for specific bugs or weaknesses in a web page. By feeding different pieces of bad data, for example, an attacker can determine the order of authentication in a script, (from the line number errors) as well as probe for exploits that may be exploited in different locations in the script. A filesystem or general PHP error can indicate what permissions the web server has, as well as the structure and organization of files on the web server. Developer written error code can aggravate this problem, leading to easy exploitation of formerly "hidden" information. There are three major solutions to this issue. The first is to scrutinize all functions, and attempt to compensate for the bulk of the errors. The second is to disable error reporting entirely on the running code. The third is to use PHP's custom error handling functions to create your own error handler. Depending on your security policy, you may find all three to be applicable to your situation. One way of catching this issue ahead of time is to make use of PHP's own error_reporting(), to help you secure your code and find variable usage that may be dangerous. By testing your code, prior to deployment, with E_ALL, you can quickly find areas where your variables may be open to poisoning or modification in other ways. Once you are ready for deployment, you should either disable error reporting completely by setting error_reporting() to 0, or turn off the error display using the php.ini option display_errors, to insulate your code from probing. If you choose to do the latter, you should also define the path to your log file using the error_log ini directive, and turn log_errors on. Example #3 Finding dangerous variables with E_ALL ---------------------------------------------------------------------- ---------------------------------------------------------------------- Using Register Globals Warning This feature has been DEPRECATED as of PHP 5.3.0. Relying on this feature is highly discouraged. Perhaps the most controversial change in PHP is when the default value for the PHP directive register_globals went from ON to OFF in PHP >> 4.2.0. Reliance on this directive was quite common and many people didn't even know it existed and assumed it's just how PHP works. This page will explain how one can write insecure code with this directive but keep in mind that the directive itself isn't insecure but rather it's the misuse of it. When on, register_globals will inject your scripts with all sorts of variables, like request variables from HTML forms. This coupled with the fact that PHP doesn't require variable initialization means writing insecure code is that much easier. It was a difficult decision, but the PHP community decided to disable this directive by default. When on, people use variables yet really don't know for sure where they come from and can only assume. Internal variables that are defined in the script itself get mixed up with request data sent by users and disabling register_globals changes this. Let's demonstrate with an example misuse of register_globals: Example #1 Example misuse with register_globals = on When register_globals = on, our logic above may be compromised. When off, $authorized can't be set via request so it'll be fine, although it really is generally a good programming practice to initialize variables first. For example, in our example above we might have first done $authorized = false. Doing this first means our above code would work with register_globals on or off as users by default would be unauthorized. Another example is that of sessions. When register_globals = on, we could also use $username in our example below but again you must realize that $username could also come from other means, such as GET (through the URL). Example #2 Example use of sessions with register_globals on or off {$_SESSION['username']}"; } else { echo "Hello Guest
"; echo "Would you like to login?"; } ?> It's even possible to take preventative measures to warn when forging is being attempted. If you know ahead of time exactly where a variable should be coming from, you can check to see if the submitted data is coming from an inappropriate kind of submission. While it doesn't guarantee that data has not been forged, it does require an attacker to guess the right kind of forging. If you don't care where the request data comes from, you can use $_REQUEST as it contains a mix of GET, POST and COOKIE data. See also the manual section on using variables from external sources. Example #3 Detecting simple variable poisoning Of course, simply turning off register_globals does not mean your code is secure. For every piece of data that is submitted, it should also be checked in other ways. Always validate your user data and initialize your variables! To check for uninitialized variables you may turn up error_reporting() to show E_NOTICE level errors. For information about emulating register_globals being On or Off, see this FAQ. Note: Superglobals: availability note Superglobal arrays such as $_GET, $_POST, and $_SERVER, etc. are available as of PHP 4.1.0. For more information, read the manual section on superglobals ---------------------------------------------------------------------- ---------------------------------------------------------------------- User Submitted Data The greatest weakness in many PHP programs is not inherent in the language itself, but merely an issue of code not being written with security in mind. For this reason, you should always take the time to consider the implications of a given piece of code, to ascertain the possible damage if an unexpected variable is submitted to it. Example #1 Dangerous Variable Usage You should always carefully examine your code to make sure that any variables being submitted from a web browser are being properly checked, and ask yourself the following questions: * Will this script only affect the intended files? * Can unusual or undesirable data be acted upon? * Can this script be used in unintended ways? * Can this be used in conjunction with other scripts in a negative manner? * Will any transactions be adequately logged? By adequately asking these questions while writing the script, rather than later, you prevent an unfortunate re-write when you need to increase your security. By starting out with this mindset, you won't guarantee the security of your system, but you can help improve it. You may also want to consider turning off register_globals, magic_quotes, or other convenience settings which may confuse you as to the validity, source, or value of a given variable. Working with PHP in error_reporting(E_ALL) mode can also help warn you about variables being used before they are checked or initialized (so you can prevent unusual data from being operated upon). ---------------------------------------------------------------------- ---------------------------------------------------------------------- Magic Quotes Table of Contents * What are Magic Quotes * Why did we use Magic Quotes * Why not to use Magic Quotes * Disabling Magic Quotes Warning This feature has been DEPRECATED as of PHP 5.3.0. Relying on this feature is highly discouraged. Magic Quotes is a process that automagically escapes incoming data to the PHP script. It's preferred to code with magic quotes off and to instead escape the data at runtime, as needed. ---------------------------------------------------------------------- What are Magic Quotes Warning This feature has been DEPRECATED as of PHP 5.3.0. Relying on this feature is highly discouraged. When on, all ' (single-quote), " (double quote), \ (backslash) and NULL characters are escaped with a backslash automatically. This is identical to what addslashes() does. There are three magic quote directives: * magic_quotes_gpc Affects HTTP Request data (GET, POST, and COOKIE). Cannot be set at runtime, and defaults to on in PHP. See also get_magic_quotes_gpc(). * magic_quotes_runtime If enabled, most functions that return data from an external source, including databases and text files, will have quotes escaped with a backslash. Can be set at runtime, and defaults to off in PHP. See also set_magic_quotes_runtime() and get_magic_quotes_runtime(). * magic_quotes_sybase If enabled, a single-quote is escaped with a single-quote instead of a backslash. If on, it completely overrides magic_quotes_gpc. Having both directives enabled means only single quotes are escaped as ''. Double quotes, backslashes and NULL's will remain untouched and unescaped. See also ini_get() for retrieving its value. ---------------------------------------------------------------------- ---------------------------------------------------------------------- Why did we use Magic Quotes Warning This feature has been DEPRECATED as of PHP 5.3.0. Relying on this feature is highly discouraged. * There is no reason to use magic quotes because they are no longer a supported part of PHP. However, they did exist and did help a few beginners blissfully and unknowingly write better (more secure) code. But, when dealing with code that relies upon this behavior it's better to update the code instead of turning magic quotes on. So why did this feature exist? Simple, to help prevent SQL Injection. Today developers are better aware of security and end up using database specific escaping mechanisms and/or prepared statements instead of relying upon features like magical quotes. ---------------------------------------------------------------------- ---------------------------------------------------------------------- Why not to use Magic Quotes Warning This feature has been DEPRECATED as of PHP 5.3.0. Relying on this feature is highly discouraged. * Portability Assuming it to be on, or off, affects portability. Use get_magic_quotes_gpc() to check for this, and code accordingly. * Performance Because not every piece of escaped data is inserted into a database, there is a performance loss for escaping all this data. Simply calling on the escaping functions (like addslashes()) at runtime is more efficient. Although php.ini-development enables these directives by default, php.ini-production disables it. This recommendation is mainly due to performance reasons. * Inconvenience Because not all data needs escaping, it's often annoying to see escaped data where it shouldn't be. For example, emailing from a form, and seeing a bunch of \' within the email. To fix, this may require excessive use of stripslashes(). ---------------------------------------------------------------------- ---------------------------------------------------------------------- Disabling Magic Quotes The magic_quotes_gpc directive may only be disabled at the system level, and not at runtime. In otherwords, use of ini_set() is not an option. Example #1 Disabling magic quotes server side An example that sets the value of these directives to Off in php.ini. For additional details, read the manual section titled How to change configuration settings. ; Magic quotes ; ; Magic quotes for incoming GET/POST/Cookie data. magic_quotes_gpc = Off ; Magic quotes for runtime-generated data, e.g. data from SQL, from exec(), etc. magic_quotes_runtime = Off ; Use Sybase-style magic quotes (escape ' with '' instead of \'). magic_quotes_sybase = Off If access to the server configuration is unavailable, use of .htaccess is also an option. For example: php_flag magic_quotes_gpc Off In the interest of writing portable code (code that works in any environment), like if setting at the server level is not possible, here's an example to disable magic_quotes_gpc at runtime. This method is inefficient so it's preferred to instead set the appropriate directives elsewhere. Example #2 Disabling magic quotes at runtime $v) { unset($process[$key][$k]); if (is_array($v)) { $process[$key][stripslashes($k)] = $v; $process[] = &$process[$key][stripslashes($k)]; } else { $process[$key][stripslashes($k)] = stripslashes($v); } } } unset($process); } ?> ---------------------------------------------------------------------- ---------------------------------------------------------------------- ---------------------------------------------------------------------- Hiding PHP In general, security by obscurity is one of the weakest forms of security. But in some cases, every little bit of extra security is desirable. A few simple techniques can help to hide PHP, possibly slowing down an attacker who is attempting to discover weaknesses in your system. By setting expose_php to off in your php.ini file, you reduce the amount of information available to them. Another tactic is to configure web servers such as apache to parse different filetypes through PHP, either with an .htaccess directive, or in the apache configuration file itself. You can then use misleading file extensions: Example #1 Hiding PHP as another language # Make PHP code look like other code types AddType application/x-httpd-php .asp .py .pl Or obscure it completely: Example #2 Using unknown types for PHP extensions # Make PHP code look like unknown types AddType application/x-httpd-php .bop .foo .133t Or hide it as HTML code, which has a slight performance hit because all HTML will be parsed through the PHP engine: Example #3 Using HTML types for PHP extensions # Make all PHP code look like HTML AddType application/x-httpd-php .htm .html For this to work effectively, you must rename your PHP files with the above extensions. While it is a form of security through obscurity, it's a minor preventative measure with few drawbacks. ---------------------------------------------------------------------- ---------------------------------------------------------------------- Keeping Current PHP, like any other large system, is under constant scrutiny and improvement. Each new version will often include both major and minor changes to enhance security and repair any flaws, configuration mishaps, and other issues that will affect the overall security and stability of your system. Like other system-level scripting languages and programs, the best approach is to update often, and maintain awareness of the latest versions and their changes. ---------------------------------------------------------------------- * Introduction * General considerations * Installed as CGI binary * Possible attacks * Case 1: only public files served * Case 2: using cgi.force_redirect * Case 3: setting doc_root or user_dir * Case 4: PHP parser outside of web tree * Installed as an Apache module * Filesystem Security * Null bytes related issues * Database Security * Designing Databases * Connecting to Database * Encrypted Storage Model * SQL Injection * Error Reporting * Using Register Globals * User Submitted Data * Magic Quotes * What are Magic Quotes * Why did we use Magic Quotes * Why not to use Magic Quotes * Disabling Magic Quotes * Hiding PHP * Keeping Current ---------------------------------------------------------------------- ---------------------------------------------------------------------- Features ---------------------------------------------------------------------- HTTP authentication with PHP It is possible to use the header() function to send an "Authentication Required" message to the client browser causing it to pop up a Username/Password input window. Once the user has filled in a username and a password, the URL containing the PHP script will be called again with the predefined variables PHP_AUTH_USER, PHP_AUTH_PW, and AUTH_TYPE set to the user name, password and authentication type respectively. These predefined variables are found in the $_SERVER and $HTTP_SERVER_VARS arrays. Both "Basic" and "Digest" (since PHP 5.1.0) authentication methods are supported. See the header() function for more information. Note: PHP Version Note Superglobals, such as $_SERVER, became available in PHP >> 4.1.0. An example script fragment which would force client authentication on a page is as follows: Example #1 Basic HTTP Authentication example Hello {$_SERVER['PHP_AUTH_USER']}.

"; echo "

You entered {$_SERVER['PHP_AUTH_PW']} as your password.

"; } ?> Example #2 Digest HTTP Authentication example This example shows you how to implement a simple Digest HTTP authentication script. For more information read the >> RFC 2617. password $users = array('admin' => 'mypass', 'guest' => 'guest'); if (empty($_SERVER['PHP_AUTH_DIGEST'])) { header('HTTP/1.1 401 Unauthorized'); header('WWW-Authenticate: Digest realm="'.$realm. '",qop="auth",nonce="'.uniqid().'",opaque="'.md5($realm).'"'); die('Text to send if user hits Cancel button'); } // analyze the PHP_AUTH_DIGEST variable if (!($data = http_digest_parse($_SERVER['PHP_AUTH_DIGEST'])) || !isset($users[$data['username']])) die('Wrong Credentials!'); // generate the valid response $A1 = md5($data['username'] . ':' . $realm . ':' . $users[$data['username']]); $A2 = md5($_SERVER['REQUEST_METHOD'].':'.$data['uri']); $valid_response = md5($A1.':'.$data['nonce'].':'.$data['nc'].':'.$data['cnonce'].':'.$data['qop'].':'.$A2); if ($data['response'] != $valid_response) die('Wrong Credentials!'); // ok, valid username & password echo 'Your are logged in as: ' . $data['username']; // function to parse the http auth header function http_digest_parse($txt) { // protect against missing data $needed_parts = array('nonce'=>1, 'nc'=>1, 'cnonce'=>1, 'qop'=>1, 'username'=>1, 'uri'=>1, 'response'=>1); $data = array(); $keys = implode('|', array_keys($needed_parts)); preg_match_all('@(' . $keys . ')=(?:([\'"])([^\2]+?)\2|([^\s,]+))@', $txt, $matches, PREG_SET_ORDER); foreach ($matches as $m) { $data[$m[1]] = $m[3] ? $m[3] : $m[4]; unset($needed_parts[$m[1]]); } return $needed_parts ? false : $data; } ?> Note: Compatibility Note Please be careful when coding the HTTP header lines. In order to guarantee maximum compatibility with all clients, the keyword "Basic" should be written with an uppercase "B", the realm string must be enclosed in double (not single) quotes, and exactly one space should precede the 401 code in the HTTP/1.0 401 header line. Authentication parameters have to be comma-separated as seen in the digest example above. Instead of simply printing out PHP_AUTH_USER and PHP_AUTH_PW, as done in the above example, you may want to check the username and password for validity. Perhaps by sending a query to a database, or by looking up the user in a dbm file. Watch out for buggy Internet Explorer browsers out there. They seem very picky about the order of the headers. Sending the WWW-Authenticate header before the HTTP/1.0 401 header seems to do the trick for now. As of PHP 4.3.0, in order to prevent someone from writing a script which reveals the password for a page that was authenticated through a traditional external mechanism, the PHP_AUTH variables will not be set if external authentication is enabled for that particular page and safe mode is enabled. Regardless, REMOTE_USER can be used to identify the externally-authenticated user. So, you can use $_SERVER['REMOTE_USER']. Note: Configuration Note PHP uses the presence of an AuthType directive to determine whether external authentication is in effect. Note, however, that the above does not prevent someone who controls a non-authenticated URL from stealing passwords from authenticated URLs on the same server. Both Netscape Navigator and Internet Explorer will clear the local browser window's authentication cache for the realm upon receiving a server response of 401. This can effectively "log out" a user, forcing them to re-enter their username and password. Some people use this to "time out" logins, or provide a "log-out" button. Example #3 HTTP Authentication example forcing a new name/password Welcome: " . htmlspecialchars($_SERVER['PHP_AUTH_USER']) . "
"; echo "Old: " . htmlspecialchars($_REQUEST['OldAuth']); echo "
\n"; echo "\n"; echo "\n"; echo "\n"; echo "

\n"; } ?> This behavior is not required by the HTTP Basic authentication standard, so you should never depend on this. Testing with Lynx has shown that Lynx does not clear the authentication credentials with a 401 server response, so pressing back and then forward again will open the resource as long as the credential requirements haven't changed. The user can press the '_' key to clear their authentication information, however. Also note that until PHP 4.3.3, HTTP Authentication did not work using Microsoft's IIS server with the CGI version of PHP due to a limitation of IIS. In order to get it to work in PHP 4.3.3+, you must edit your IIS configuration "Directory Security". Click on "Edit" and only check "Anonymous Access", all other fields should be left unchecked. Another limitation is if you're using the IIS module (ISAPI) and PHP 4, you may not use the PHP_AUTH_* variables but instead, the variable HTTP_AUTHORIZATION is available. For example, consider the following code: list($user, $pw) = explode(':', base64_decode(substr($_SERVER['HTTP_AUTHORIZATION'], 6))); Note: IIS Note: For HTTP Authentication to work with IIS, the PHP directive cgi.rfc2616_headers must be set to 0 (the default value). Note: If safe mode is enabled, the uid of the script is added to the realm part of the WWW-Authenticate header. ---------------------------------------------------------------------- ---------------------------------------------------------------------- Cookies PHP transparently supports HTTP cookies. Cookies are a mechanism for storing data in the remote browser and thus tracking or identifying return users. You can set cookies using the setcookie() or setrawcookie() function. Cookies are part of the HTTP header, so setcookie() must be called before any output is sent to the browser. This is the same limitation that header() has. You can use the output buffering functions to delay the script output until you have decided whether or not to set any cookies or send any headers. Any cookies sent to you from the client will automatically be included into a $_COOKIE auto-global array if variables_order contains "C". If you wish to assign multiple values to a single cookie, just add [] to the cookie name. Depending on register_globals, regular PHP variables can be created from cookies. However it's not recommended to rely on them as this feature is often turned off for the sake of security. $HTTP_COOKIE_VARS is also set in earlier versions of PHP when the track_vars configuration variable is set. (This setting is always on since PHP 4.0.3.) For more details, including notes on browser bugs, see the setcookie() and setrawcookie() function. ---------------------------------------------------------------------- ---------------------------------------------------------------------- Sessions Session support in PHP consists of a way to preserve certain data across subsequent accesses. This enables you to build more customized applications and increase the appeal of your web site. All information is in the Session reference section. ---------------------------------------------------------------------- ---------------------------------------------------------------------- Dealing with XForms >> XForms defines a variation on traditional webforms which allows them to be used on a wider variety of platforms and browsers or even non-traditional media such as PDF documents. The first key difference in XForms is how the form is sent to the client. >> XForms for HTML Authors contains a detailed description of how to create XForms, for the purpose of this tutorial we'll only be looking at a simple example. Example #1 A simple XForms search form Search The above form displays a text input box (named q), and a submit button. When the submit button is clicked, the form will be sent to the page referred to by action. Here's where it starts to look different from your web application's point of view. In a normal HTML form, the data would be sent as application/x-www-form-urlencoded, in the XForms world however, this information is sent as XML formatted data. If you're choosing to work with XForms then you probably want that data as XML, in that case, look in $HTTP_RAW_POST_DATA where you'll find the XML document generated by the browser which you can pass into your favorite XSLT engine or document parser. If you're not interested in formatting and just want your data to be loaded into the traditional $_POST variable, you can instruct the client browser to send it as application/x-www-form-urlencoded by changing the method attribute to urlencoded-post. Example #2 Using an XForm to populate $_POST Search Note: As of this writing, many browsers do not support XForms. Check your browser version if the above examples fails. ---------------------------------------------------------------------- ---------------------------------------------------------------------- Handling file uploads Table of Contents * POST method uploads * Error Messages Explained * Common Pitfalls * Uploading multiple files * PUT method support ---------------------------------------------------------------------- POST method uploads This feature lets people upload both text and binary files. With PHP's authentication and file manipulation functions, you have full control over who is allowed to upload and what is to be done with the file once it has been uploaded. PHP is capable of receiving file uploads from any RFC-1867 compliant browser. Note: Related Configurations Note See also the file_uploads, upload_max_filesize, upload_tmp_dir, post_max_size and max_input_time directives in php.ini PHP also supports PUT-method file uploads as used by Netscape Composer and W3C's Amaya clients. See the PUT Method Support for more details. Example #1 File Upload Form A file upload screen can be built by creating a special form which looks something like this:
Send this file:
The __URL__ in the above example should be replaced, and point to a PHP file. The MAX_FILE_SIZE hidden field (measured in bytes) must precede the file input field, and its value is the maximum filesize accepted by PHP. This form element should always be used as it saves users the trouble of waiting for a big file being transferred only to find that it was too large and the transfer failed. Keep in mind: fooling this setting on the browser side is quite easy, so never rely on files with a greater size being blocked by this feature. It is merely a convenience feature for users on the client side of the application. The PHP settings (on the server side) for maximum-size, however, cannot be fooled. Note: Be sure your file upload form has attribute enctype="multipart/form-data" otherwise the file upload will not work. The global $_FILES exists as of PHP 4.1.0 (Use $HTTP_POST_FILES instead if using an earlier version). These arrays will contain all the uploaded file information. The contents of $_FILES from the example form is as follows. Note that this assumes the use of the file upload name userfile, as used in the example script above. This can be any name. $_FILES['userfile']['name'] The original name of the file on the client machine. $_FILES['userfile']['type'] The mime type of the file, if the browser provided this information. An example would be "image/gif". This mime type is however not checked on the PHP side and therefore don't take its value for granted. $_FILES['userfile']['size'] The size, in bytes, of the uploaded file. $_FILES['userfile']['tmp_name'] The temporary filename of the file in which the uploaded file was stored on the server. $_FILES['userfile']['error'] The error code associated with this file upload. This element was added in PHP 4.2.0 Files will, by default be stored in the server's default temporary directory, unless another location has been given with the upload_tmp_dir directive in php.ini. The server's default directory can be changed by setting the environment variable TMPDIR in the environment in which PHP runs. Setting it using putenv() from within a PHP script will not work. This environment variable can also be used to make sure that other operations are working on uploaded files, as well. Example #2 Validating file uploads See also the function entries for is_uploaded_file() and move_uploaded_file() for further information. The following example will process the file upload that came from a form. '; if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) { echo "File is valid, and was successfully uploaded.\n"; } else { echo "Possible file upload attack!\n"; } echo 'Here is some more debugging info:'; print_r($_FILES); print "
"; ?> The PHP script which receives the uploaded file should implement whatever logic is necessary for determining what should be done with the uploaded file. You can, for example, use the $_FILES['userfile']['size'] variable to throw away any files that are either too small or too big. You could use the $_FILES['userfile']['type'] variable to throw away any files that didn't match a certain type criteria, but use this only as first of a series of checks, because this value is completely under the control of the client and not checked on the PHP side. As of PHP 4.2.0, you could use $_FILES['userfile']['error'] and plan your logic according to the error codes. Whatever the logic, you should either delete the file from the temporary directory or move it elsewhere. If no file is selected for upload in your form, PHP will return $_FILES['userfile']['size'] as 0, and $_FILES['userfile']['tmp_name'] as none. The file will be deleted from the temporary directory at the end of the request if it has not been moved away or renamed. Example #3 Uploading array of files PHP supports HTML array feature even with files.

Pictures:

$error) { if ($error == UPLOAD_ERR_OK) { $tmp_name = $_FILES["pictures"]["tmp_name"][$key]; $name = $_FILES["pictures"]["name"][$key]; move_uploaded_file($tmp_name, "data/$name"); } } ?> File upload progress bar can be implemented by apc.rfc1867. ---------------------------------------------------------------------- ---------------------------------------------------------------------- Error Messages Explained Since PHP 4.2.0, PHP returns an appropriate error code along with the file array. The error code can be found in the error segment of the file array that is created during the file upload by PHP. In other words, the error might be found in $_FILES['userfile']['error']. UPLOAD_ERR_OK Value: 0; There is no error, the file uploaded with success. UPLOAD_ERR_INI_SIZE Value: 1; The uploaded file exceeds the upload_max_filesize directive in php.ini. UPLOAD_ERR_FORM_SIZE Value: 2; The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form. UPLOAD_ERR_PARTIAL Value: 3; The uploaded file was only partially uploaded. UPLOAD_ERR_NO_FILE Value: 4; No file was uploaded. UPLOAD_ERR_NO_TMP_DIR Value: 6; Missing a temporary folder. Introduced in PHP 4.3.10 and PHP 5.0.3. UPLOAD_ERR_CANT_WRITE Value: 7; Failed to write file to disk. Introduced in PHP 5.1.0. UPLOAD_ERR_EXTENSION Value: 8; A PHP extension stopped the file upload. PHP does not provide a way to ascertain which extension caused the file upload to stop; examining the list of loaded extensions with phpinfo() may help. Introduced in PHP 5.2.0. Note: These became PHP constants in PHP 4.3.0. ---------------------------------------------------------------------- ---------------------------------------------------------------------- Common Pitfalls The MAX_FILE_SIZE item cannot specify a file size greater than the file size that has been set in the upload_max_filesize in the php.ini file. The default is 2 megabytes. If a memory limit is enabled, a larger memory_limit may be needed. Make sure you set memory_limit large enough. If max_execution_time is set too small, script execution may be exceeded by the value. Make sure you set max_execution_time large enough. Note: max_execution_time only affects the execution time of the script itself. Any time spent on activity that happens outside the execution of the script such as system calls using system(), the sleep() function, database queries, time taken by the file upload process, etc. is not included when determining the maximum time that the script has been running. Warning max_input_time sets the maximum time, in seconds, the script is allowed to receive input; this includes file uploads. For large or multiple files, or users on slower connections, the default of 60 seconds may be exceeded. If post_max_size is set too small, large files cannot be uploaded. Make sure you set post_max_size large enough. Since PHP 5.2.12, the max_file_uploads configuration setting controls the maximum number of files that can uploaded in one request. If more files are uploaded than the limit, then $_FILES will stop processing files once the limit is reached. For example, if max_file_uploads is set to 10, then $_FILES will never contain more than 10 items. Not validating which file you operate on may mean that users can access sensitive information in other directories. Please note that the CERN httpd seems to strip off everything starting at the first whitespace in the content-type mime header it gets from the client. As long as this is the case, CERN httpd will not support the file upload feature. Due to the large amount of directory listing styles we cannot guarantee that files with exotic names (like containing spaces) are handled properly. A developer may not mix normal input fields and file upload fields in the same form variable (by using an input name like foo[]). ---------------------------------------------------------------------- ---------------------------------------------------------------------- Uploading multiple files Multiple files can be uploaded using different name for input. It is also possible to upload multiple files simultaneously and have the information organized automatically in arrays for you. To do so, you need to use the same array submission syntax in the HTML form as you do with multiple selects and checkboxes: Example #1 Uploading multiple files
Send these files:


When the above form is submitted, the arrays $_FILES['userfile'], $_FILES['userfile']['name'], and $_FILES['userfile']['size'] will be initialized (as well as in $HTTP_POST_FILES for PHP versions prior to 4.1.0). When register_globals is on, globals for uploaded files are also initialized. Each of these will be a numerically indexed array of the appropriate values for the submitted files. For instance, assume that the filenames /home/test/review.html and /home/test/xwp.out are submitted. In this case, $_FILES['userfile']['name'][0] would contain the value review.html, and $_FILES['userfile']['name'][1] would contain the value xwp.out. Similarly, $_FILES['userfile']['size'][0] would contain review.html's file size, and so forth. $_FILES['userfile']['name'][0], $_FILES['userfile']['tmp_name'][0], $_FILES['userfile']['size'][0], and $_FILES['userfile']['type'][0] are also set. Warning Since PHP 5.2.12, the max_file_uploads configuration setting acts as a limit on the number of files that can be uploaded in one request. You will need to ensure that your form does not try to upload more files in one request than this limit. ---------------------------------------------------------------------- ---------------------------------------------------------------------- PUT method support PHP provides support for the HTTP PUT method used by some clients to store files on a server. PUT requests are much simpler than a file upload using POST requests and they look something like this: PUT /path/filename.html HTTP/1.1 This would normally mean that the remote client would like to save the content that follows as: /path/filename.html in your web tree. It is obviously not a good idea for Apache or PHP to automatically let everybody overwrite any files in your web tree. So, to handle such a request you have to first tell your web server that you want a certain PHP script to handle the request. In Apache you do this with the Script directive. It can be placed almost anywhere in your Apache configuration file. A common place is inside a block or perhaps inside a block. A line like this would do the trick: Script PUT /put.php This tells Apache to send all PUT requests for URIs that match the context in which you put this line to the put.php script. This assumes, of course, that you have PHP enabled for the .php extension and PHP is active. The destination resource for all PUT requests to this script has to be the script itself, not a filename the uploaded file should have. With PHP you would then do something like the following in your put.php. This would copy the contents of the uploaded file to the file myputfile.ext on the server. You would probably want to perform some checks and/or authenticate the user before performing this file copy. Example #1 Saving HTTP PUT files ---------------------------------------------------------------------- ---------------------------------------------------------------------- ---------------------------------------------------------------------- Using remote files As long as allow_url_fopen is enabled in php.ini, you can use HTTP and FTP URLs with most of the functions that take a filename as a parameter. In addition, URLs can be used with the include(), include_once(), require() and require_once() statements (since PHP 5.2.0, allow_url_include must be enabled for these). See Supported Protocols and Wrappers for more information about the protocols supported by PHP. Note: In PHP 4.0.3 and older, in order to use URL wrappers, you were required to configure PHP using the configure option --enable-url-fopen-wrapper . Note: The Windows versions of PHP earlier than PHP 4.3 did not support remote file accessing for the following functions: include(), include_once(), require(), require_once(), and the imagecreatefromXXX functions in the GD and Image Functions extension. For example, you can use this to open a file on a remote web server, parse the output for the data you want, and then use that data in a database query, or simply to output it in a style matching the rest of your website. Example #1 Getting the title of a remote page Unable to open remote file.\n"; exit; } while (!feof ($file)) { $line = fgets ($file, 1024); /* This only works if the title and its tags are on one line */ if (preg_match ("@\(.*)\@i", $line, $out)) { $title = $out[1]; break; } } fclose($file); ?> You can also write to files on an FTP server (provided that you have connected as a user with the correct access rights). You can only create new files using this method; if you try to overwrite a file that already exists, the fopen() call will fail. To connect as a user other than 'anonymous', you need to specify the username (and possibly password) within the URL, such as 'ftp://user:password@ftp.example.com/path/to/file'. (You can use the same sort of syntax to access files via HTTP when they require Basic authentication.) Example #2 Storing data on a remote server Unable to open remote file for writing.\n"; exit; } /* Write the data here. */ fwrite ($file, $_SERVER['HTTP_USER_AGENT'] . "\n"); fclose ($file); ?> Note: You might get the idea from the example above that you can use this technique to write to a remote log file. Unfortunately that would not work because the fopen() call will fail if the remote file already exists. To do distributed logging like that, you should take a look at syslog(). ---------------------------------------------------------------------- ---------------------------------------------------------------------- Connection handling Internally in PHP a connection status is maintained. There are 3 possible states: * 0 - NORMAL * 1 - ABORTED * 2 - TIMEOUT When a PHP script is running normally the NORMAL state, is active. If the remote client disconnects the ABORTED state flag is turned on. A remote client disconnect is usually caused by the user hitting his STOP button. If the PHP-imposed time limit (see set_time_limit()) is hit, the TIMEOUT state flag is turned on. You can decide whether or not you want a client disconnect to cause your script to be aborted. Sometimes it is handy to always have your scripts run to completion even if there is no remote browser receiving the output. The default behaviour is however for your script to be aborted when the remote client disconnects. This behaviour can be set via the ignore_user_abort php.ini directive as well as through the corresponding php_value ignore_user_abort Apache httpd.conf directive or with the ignore_user_abort() function. If you do not tell PHP to ignore a user abort and the user aborts, your script will terminate. The one exception is if you have registered a shutdown function using register_shutdown_function(). With a shutdown function, when the remote user hits his STOP button, the next time your script tries to output something PHP will detect that the connection has been aborted and the shutdown function is called. This shutdown function will also get called at the end of your script terminating normally, so to do something different in case of a client disconnect you can use the connection_aborted() function. This function will return TRUE if the connection was aborted. Your script can also be terminated by the built-in script timer. The default timeout is 30 seconds. It can be changed using the max_execution_time php.ini directive or the corresponding php_value max_execution_time Apache httpd.conf directive as well as with the set_time_limit() function. When the timer expires the script will be aborted and as with the above client disconnect case, if a shutdown function has been registered it will be called. Within this shutdown function you can check to see if a timeout caused the shutdown function to be called by calling the connection_status() function. This function will return 2 if a timeout caused the shutdown function to be called. One thing to note is that both the ABORTED and the TIMEOUT states can be active at the same time. This is possible if you tell PHP to ignore user aborts. PHP will still note the fact that a user may have broken the connection, but the script will keep running. If it then hits the time limit it will be aborted and your shutdown function, if any, will be called. At this point you will find that connection_status() returns 3. ---------------------------------------------------------------------- ---------------------------------------------------------------------- Persistent Database Connections Persistent connections are links that do not close when the execution of your script ends. When a persistent connection is requested, PHP checks if there's already an identical persistent connection (that remained open from earlier) - and if it exists, it uses it. If it does not exist, it creates the link. An 'identical' connection is a connection that was opened to the same host, with the same username and the same password (where applicable). People who aren't thoroughly familiar with the way web servers work and distribute the load may mistake persistent connects for what they're not. In particular, they do not give you an ability to open 'user sessions' on the same link, they do not give you an ability to build up a transaction efficiently, and they don't do a whole lot of other things. In fact, to be extremely clear about the subject, persistent connections don't give you any functionality that wasn't possible with their non-persistent brothers. Why? This has to do with the way web servers work. There are three ways in which your web server can utilize PHP to generate web pages. The first method is to use PHP as a CGI "wrapper". When run this way, an instance of the PHP interpreter is created and destroyed for every page request (for a PHP page) to your web server. Because it is destroyed after every request, any resources that it acquires (such as a link to an SQL database server) are closed when it is destroyed. In this case, you do not gain anything from trying to use persistent connections -- they simply don't persist. The second, and most popular, method is to run PHP as a module in a multiprocess web server, which currently only includes Apache. A multiprocess server typically has one process (the parent) which coordinates a set of processes (its children) who actually do the work of serving up web pages. When a request comes in from a client, it is handed off to one of the children that is not already serving another client. This means that when the same client makes a second request to the server, it may be served by a different child process than the first time. When opening a persistent connection, every following page requesting SQL services can reuse the same established connection to the SQL server. The last method is to use PHP as a plug-in for a multithreaded web server. Currently PHP 4 has support for ISAPI, WSAPI, and NSAPI (on Windows), which all allow PHP to be used as a plug-in on multithreaded servers like Netscape FastTrack (iPlanet), Microsoft's Internet Information Server (IIS), and O'Reilly's WebSite Pro. The behavior is essentially the same as for the multiprocess model described before. If persistent connections don't have any added functionality, what are they good for? The answer here is extremely simple -- efficiency. Persistent connections are good if the overhead to create a link to your SQL server is high. Whether or not this overhead is really high depends on many factors. Like, what kind of database it is, whether or not it sits on the same computer on which your web server sits, how loaded the machine the SQL server sits on is and so forth. The bottom line is that if that connection overhead is high, persistent connections help you considerably. They cause the child process to simply connect only once for its entire lifespan, instead of every time it processes a page that requires connecting to the SQL server. This means that for every child that opened a persistent connection will have its own open persistent connection to the server. For example, if you had 20 different child processes that ran a script that made a persistent connection to your SQL server, you'd have 20 different connections to the SQL server, one from each child. Note, however, that this can have some drawbacks if you are using a database with connection limits that are exceeded by persistent child connections. If your database has a limit of 16 simultaneous connections, and in the course of a busy server session, 17 child threads attempt to connect, one will not be able to. If there are bugs in your scripts which do not allow the connections to shut down (such as infinite loops), the database with only 16 connections may be rapidly swamped. Check your database documentation for information on handling abandoned or idle connections. Warning There are a couple of additional caveats to keep in mind when using persistent connections. One is that when using table locking on a persistent connection, if the script for whatever reason cannot release the lock, then subsequent scripts using the same connection will block indefinitely and may require that you either restart the httpd server or the database server. Another is that when using transactions, a transaction block will also carry over to the next script which uses that connection if script execution ends before the transaction block does. In either case, you can use register_shutdown_function() to register a simple cleanup function to unlock your tables or roll back your transactions. Better yet, avoid the problem entirely by not using persistent connections in scripts which use table locks or transactions (you can still use them elsewhere). An important summary. Persistent connections were designed to have one-to-one mapping to regular connections. That means that you should always be able to replace persistent connections with non-persistent connections, and it won't change the way your script behaves. It may (and probably will) change the efficiency of the script, but not its behavior! See also fbsql_pconnect(), ibase_pconnect(), ifx_pconnect(), ingres_pconnect(), msql_pconnect(), mssql_pconnect(), mysql_pconnect(), ociplogon(), odbc_pconnect(), oci_pconnect(), pfsockopen(), pg_pconnect(), and sybase_pconnect(). ---------------------------------------------------------------------- ---------------------------------------------------------------------- Safe Mode Table of Contents * Security and Safe Mode * Functions restricted/disabled by safe mode The PHP safe mode is an attempt to solve the shared-server security problem. It is architecturally incorrect to try to solve this problem at the PHP level, but since the alternatives at the web server and OS levels aren't very realistic, many people, especially ISP's, use safe mode for now. Warning This feature has been DEPRECATED as of PHP 5.3.0. Relying on this feature is highly discouraged. ---------------------------------------------------------------------- Security and Safe Mode Security and Safe Mode Configuration Directives Name Default Changeable Changelog safe_mode "0" PHP_INI_SYSTEM Removed in PHP 5.4.0. Available since PHP safe_mode_gid "0" PHP_INI_SYSTEM 4.1.0. Removed in PHP 5.4.0. Available since PHP safe_mode_include_dir NULL PHP_INI_SYSTEM 4.1.0. Removed in PHP 5.4.0. safe_mode_exec_dir "" PHP_INI_SYSTEM Removed in PHP 5.4.0. safe_mode_allowed_env_vars "PHP_" PHP_INI_SYSTEM Removed in PHP 5.4.0. safe_mode_protected_env_vars "LD_LIBRARY_PATH" PHP_INI_SYSTEM Removed in PHP 5.4.0. For further details and definitions of the PHP_INI_* modes, see the Where a configuration setting may be set. Here's a short explanation of the configuration directives. safe_mode boolean Whether to enable PHP's safe mode. If PHP is compiled with --enable-safe-mode then defaults to On, otherwise Off. Warning This feature has been DEPRECATED as of PHP 5.3.0. Relying on this feature is highly discouraged. safe_mode_gid boolean By default, Safe Mode does a UID compare check when opening files. If you want to relax this to a GID compare, then turn on safe_mode_gid. Whether to use UID (FALSE) or GID (TRUE) checking upon file access. safe_mode_include_dir string UID/GID checks are bypassed when including files from this directory and its subdirectories (directory must also be in include_path or full path must including). As of PHP 4.2.0, this directive can take a colon (semi-colon on Windows) separated path in a fashion similar to the include_path directive, rather than just a single directory. The restriction specified is actually a prefix, not a directory name. This means that "safe_mode_include_dir = /dir/incl" also allows access to "/dir/include" and "/dir/incls" if they exist. When you want to restrict access to only the specified directory, end with a slash. For example: "safe_mode_include_dir = /dir/incl/" If the value of this directive is empty, no files with different UID/GID can be included in PHP 4.2.3 and as of PHP 4.3.3. In earlier versions, all files could be included. safe_mode_exec_dir string If PHP is used in safe mode, system() and the other functions executing system programs refuse to start programs that are not in this directory. You have to use / as directory separator on all environments including Windows. safe_mode_allowed_env_vars string Setting certain environment variables may be a potential security breach. This directive contains a comma-delimited list of prefixes. In Safe Mode, the user may only alter environment variables whose names begin with the prefixes supplied here. By default, users will only be able to set environment variables that begin with PHP_ (e.g. PHP_FOO=BAR). Note: If this directive is empty, PHP will let the user modify ANY environment variable! safe_mode_protected_env_vars string This directive contains a comma-delimited list of environment variables that the end user won't be able to change using putenv(). These variables will be protected even if safe_mode_allowed_env_vars is set to allow to change them. See also: open_basedir, disable_functions, disable_classes, register_globals, display_errors, and log_errors. When safe_mode is on, PHP checks to see if the owner of the current script matches the owner of the file to be operated on by a file function or its directory. For example: -rw-rw-r-- 1 rasmus rasmus 33 Jul 1 19:20 script.php -rw-r--r-- 1 root root 1116 May 26 18:01 /etc/passwd Running script.php: results in this error when safe mode is enabled: Warning: SAFE MODE Restriction in effect. The script whose uid is 500 is not allowed to access /etc/passwd owned by uid 0 in /docroot/script.php on line 2 However, there may be environments where a strict UID check is not appropriate and a relaxed GID check is sufficient. This is supported by means of the safe_mode_gid switch. Setting it to On performs the relaxed GID checking, setting it to Off (the default) performs UID checking. If instead of safe_mode, you set an open_basedir directory then all file operations will be limited to files under the specified directory. For example (Apache httpd.conf example): php_admin_value open_basedir /docroot If you run the same script.php with this open_basedir setting then this is the result: Warning: open_basedir restriction in effect. File is in wrong directory in /docroot/script.php on line 2 You can also disable individual functions. Note that the disable_functions directive can not be used outside of the php.ini file which means that you cannot disable functions on a per-virtualhost or per-directory basis in your httpd.conf file. If we add this to our php.ini file: disable_functions = readfile,system Then we get this output: Warning: readfile() has been disabled for security reasons in /docroot/script.php on line 2 Warning These PHP restrictions are not valid in executed binaries, of course. ---------------------------------------------------------------------- ---------------------------------------------------------------------- Functions restricted/disabled by safe mode This is a still probably incomplete and possibly incorrect listing of the functions limited by safe mode. Safe mode limited functions Function Limitations Checks whether the files or directories being dbmopen() operated upon have the same UID (owner) as the script that is being executed. Checks whether the files or directories being dbase_open() operated upon have the same UID (owner) as the script that is being executed. Checks whether the files or directories being filepro() operated upon have the same UID (owner) as the script that is being executed. Checks whether the files or directories being filepro_rowcount() operated upon have the same UID (owner) as the script that is being executed. Checks whether the files or directories being filepro_retrieve() operated upon have the same UID (owner) as the script that is being executed. ifx_* sql_safe_mode restrictions, (!= safe mode) ingres_* sql_safe_mode restrictions, (!= safe mode) mysql_* sql_safe_mode restrictions, (!= safe mode) Checks whether the files or directories being pg_lo_import() operated upon have the same UID (owner) as the script that is being executed. Checks whether the directory in which the script posix_mkfifo() is operating has the same UID (owner) as the script that is being executed. Obeys the safe_mode_protected_env_vars and putenv() safe_mode_allowed_env_vars ini-directives. See also the documentation on putenv() Checks whether the files or directories being move_uploaded_file() operated upon have the same UID (owner) as the script that is being executed. Checks whether the directory in which the script chdir() is operating has the same UID (owner) as the script that is being executed. dl() This function is disabled when PHP is running in safe mode. backtick operator This function is disabled when PHP is running in safe mode. shell_exec() (functional This function is disabled when PHP is running in equivalent of backticks) safe mode. You can only execute executables within the safe_mode_exec_dir. For practical reasons it's exec() currently not allowed to have .. components in the path to the executable. escapeshellcmd() is executed on the argument of this function. You can only execute executables within the safe_mode_exec_dir. For practical reasons it's system() currently not allowed to have .. components in the path to the executable. escapeshellcmd() is executed on the argument of this function. You can only execute executables within the safe_mode_exec_dir. For practical reasons it's passthru() currently not allowed to have .. components in the path to the executable. escapeshellcmd() is executed on the argument of this function. You can only execute executables within the safe_mode_exec_dir. For practical reasons it's popen() currently not allowed to have .. components in the path to the executable. escapeshellcmd() is executed on the argument of this function. Checks whether the directory in which the script fopen() is operating has the same UID (owner) as the script that is being executed. Checks whether the directory in which the script mkdir() is operating has the same UID (owner) as the script that is being executed. Checks whether the directory in which the script rmdir() is operating has the same UID (owner) as the script that is being executed. Checks whether the files or directories being operated upon have the same UID (owner) as the rename() script that is being executed. Checks whether the directory in which the script is operating has the same UID (owner) as the script that is being executed. Checks whether the files or directories being operated upon have the same UID (owner) as the unlink() script that is being executed. Checks whether the directory in which the script is operating has the same UID (owner) as the script that is being executed. Checks whether the files or directories being operated upon have the same UID (owner) as the copy() script that is being executed. Checks whether the directory in which the script is operating has the same UID (owner) as the script that is being executed. (on source and target) Checks whether the files or directories being chgrp() operated upon have the same UID (owner) as the script that is being executed. Checks whether the files or directories being chown() operated upon have the same UID (owner) as the script that is being executed. Checks whether the files or directories being chmod() operated upon have the same UID (owner) as the script that is being executed. In addition, you cannot set the SUID, SGID and sticky bits Checks whether the files or directories being operated upon have the same UID (owner) as the touch() script that is being executed. Checks whether the directory in which the script is operating has the same UID (owner) as the script that is being executed. Checks whether the files or directories being operated upon have the same UID (owner) as the script that is being executed. Checks whether symlink() the directory in which the script is operating has the same UID (owner) as the script that is being executed. (note: only the target is checked) Checks whether the files or directories being operated upon have the same UID (owner) as the script that is being executed. Checks whether link() the directory in which the script is operating has the same UID (owner) as the script that is being executed. (note: only the target is checked) In safe mode, headers beginning with apache_request_headers() authorization (case-insensitive) will not be returned. In safe mode, the uid of the script is added to header() the realm part of the WWW-Authenticate header if you set this header (used for HTTP Authentication). In safe mode, the variables PHP_AUTH_USER, PHP_AUTH_PW, and AUTH_TYPE are not available in PHP_AUTH variables $_SERVER. Regardless, you can still use REMOTE_USER for the USER. (note: only affected since PHP 4.3.0) Checks whether the files or directories being operated upon have the same UID (owner) as the highlight_file(), script that is being executed. Checks whether show_source() the directory in which the script is operating has the same UID (owner) as the script that is being executed. (note: only affected since PHP 4.2.1) Checks whether the files or directories being operated upon have the same UID (owner) as the script that is being executed. Checks whether parse_ini_file() the directory in which the script is operating has the same UID (owner) as the script that is being executed. (note: only affected since PHP 4.2.1) set_time_limit() Has no effect when PHP is running in safe mode. max_execution_time Has no effect when PHP is running in safe mode. mail() In safe mode, the fifth parameter is disabled. (note: only affected since PHP 4.2.3) The owner of a script must be the same as owner session_start() of a session.save_path directory if the default files session.save_handler is used. Checks whether the files or directories being operated upon have the same UID (owner) as the All filesystem and stream script that is being executed. Checks whether functions. the directory in which the script is operating has the same UID (owner) as the script that is being executed. (see the safe_mode_include_dir php.ini option. ---------------------------------------------------------------------- ---------------------------------------------------------------------- ---------------------------------------------------------------------- Using PHP from the command line Table of Contents * Introduction * Differences to other SAPIs * Options * Usage * I/O streams * Interactive shell * Built-in web server ---------------------------------------------------------------------- Introduction PHP supports a CLI SAPI as of PHP 4.3.0. The main focus of this SAPI is for developing shell applications with PHP. There are quite a few differences between the CLI SAPI and other SAPIs which are explained in this chapter. It is worth mentioning that CLI and CGI are different SAPIs although they do share many of the same behaviors. The CLI SAPI is enabled by default using --enable-cli , but may be disabled using the --disable-cli option when running ./configure. The name, location and existence of the CLI/CGI binaries will differ depending on how PHP is installed on your system. By default when executing make, both the CGI and CLI are built and placed as sapi/cgi/php-cgi and sapi/cli/php respectively, in your PHP source directory. You will note that both are named php. What happens during make install depends on your configure line. If a module SAPI is chosen during configure, such as apxs, or the --disable-cgi option is used, the CLI is copied to {PREFIX}/bin/php during make install otherwise the CGI is placed there. So, for example, if --with-apxs is in your configure line then the CLI is copied to {PREFIX}/bin/php during make install. If you want to override the installation of the CGI binary, use make install-cli after make install. Alternatively you can specify --disable-cgi in your configure line. Note: Because both --enable-cli and --enable-cgi are enabled by default, simply having --enable-cli in your configure line does not necessarily mean the CLI will be copied as {PREFIX}/bin/php during make install. As of PHP 5, the CLI binary is distributed in the main folder as php.exe on Windows. The CGI version is distributed as php-cgi.exe. Additionally, a php-win.exe is distributed if PHP is configured using --enable-cli-win32 . This does the same as the CLI version, except that it doesn't output anything and thus provides no console. Note: What SAPI do I have? From a shell, typing php -v will tell you whether php is CGI or CLI. See also the function php_sapi_name() and the constant PHP_SAPI. Note: A Unix manual page is available by typing man php in the shell environment. ---------------------------------------------------------------------- ---------------------------------------------------------------------- Differences to other SAPIs Remarkable differences of the CLI SAPI compared to other SAPIs: * Unlike the CGI SAPI, no headers are written to the output. Though the CGI SAPI provides a way to suppress HTTP headers, there's no equivalent switch to enable them in the CLI SAPI. CLI is started up in quiet mode by default, though the -q and --no-header switches are kept for compatibility so that it is possible to use older CGI scripts. It does not change the working directory to that of the script. (-C and --no-chdir switches kept for compatibility) Plain text error messages (no HTML formatting). * There are certain php.ini directives which are overridden by the CLI SAPI because they do not make sense in shell environments: Overridden php.ini directives Directive CLI SAPI default Comment value Defaults to FALSE, as it can be quite hard to read error messages html_errors FALSE in the shell enviroment when they are cluttered up with uninterpreted HTML tags. In a shell environment, it is usually desirable for output, such as from print(), echo() and friends, to be displayed implicit_flush TRUE immediately, and not held in a buffer. Nonetheless, it is still possible to use output buffering to defer or manipulate standard output. PHP in a shell environment tends to be used for a much more diverse range of purposes than typical max_execution_time 0 (unlimited) Web-based scripts, and as these can be very long-running, the maximum execution time is set to unlimited. Setting this to TRUE means that scripts executed via the CLI SAPI always have access to argc (number of arguments passed to the application) and argv (array of the actual arguments). register_argc_argv TRUE The PHP variables $argc and $argv are automatically set to the appropriate values when using the CLI SAPI. These values can also be found in the $_SERVER array, for example: $_SERVER['argv']. Although the php.ini setting is output_buffering FALSE hardcoded to FALSE, the Output buffering functions are available. max_input_time FALSE The PHP CLI doesn't not support GET, POST or file uploads. Note: These directives cannot be initialized with another value from the configuration file php.ini or a custom one (if specified). This limitation is because the values are applied after all configuration files have been parsed. However, their values can be changed during runtime (although this is not sensible for all of them, such as register_argc_argv). Note: It is recommended to set ignore_user_abort for command line scripts. See ignore_user_abort() for more information. * To ease working in the shell environment, a number of constants are defined for I/O streams . * The CLI SAPI does not change the current directory to the directory of the executed script. Example #1 Example showing the difference to the CGI SAPI: When using the CGI version, the output is: $ pwd /tmp $ php -q another_directory/test.php /tmp/another_directory This clearly shows that PHP changes its current directory to the one of the executed script. Using the CLI SAPI yields: $ pwd /tmp $ php -f another_directory/test.php /tmp This allows greater flexibility when writing shell tools in PHP. Note: The CGI SAPI supports this CLI SAPI behaviour by means of the -C switch when run from the command line. ---------------------------------------------------------------------- ---------------------------------------------------------------------- Command line options The list of command line options provided by the PHP binary can be queried at any time by running PHP with the -h switch: Usage: php [options] [-f] [--] [args...] php [options] -r [--] [args...] php [options] [-B ] -R [-E ] [--] [args...] php [options] [-B ] -F [-E ] [--] [args...] php [options] -- [args...] php [options] -a -a Run interactively -c | Look for php.ini file in this directory -n No php.ini file will be used -d foo[=bar] Define INI entry foo with value 'bar' -e Generate extended information for debugger/profiler -f Parse and execute . -h This help -i PHP information -l Syntax check only (lint) -m Show compiled in modules -r Run PHP without using script tags -B Run PHP before processing input lines -R Run PHP for every input line -F Parse and execute for every input line -E Run PHP after processing all input lines -H Hide any passed arguments from external tools. -s Output HTML syntax highlighted source. -v Version number -w Output source with stripped comments and whitespace. -z Load Zend extension . args... Arguments passed to script. Use -- args when first argument starts with - or script is read from stdin --ini Show configuration file names --rf Show information about function . --rc Show information about class . --re Show information about extension . --rz Show information about Zend extension . --ri Show configuration for extension . Command line options Option Long Option Description -a --interactive Run PHP interactively. For more information, see the Interactive shell section. -b --bindpath Bind Path for external FASTCGI Server mode (CGI only). -C --no-chdir Do not chdir to the script's directory (CGI only). -q --no-header Quiet-mode. Suppress HTTP header output (CGI only). -T --timing Measure execution time of script repeated count times (CGI only). Specifies either a directory in which to look for php.ini, or a custom INI file (which does not need to be named php.ini), e.g.: -c --php-ini $ php -c /custom/directory/ my_script.php $ php -c /custom/directory/custom-file.ini my_script.php If this option is not specified, php.ini is searched for in the default locations. -n --no-php-ini Ignore php.ini completely. Set a custom value for any of the configuration directives allowed in php.ini. The syntax is: -d configuration_directive[=value] # Omitting the value part will set the given configuration directive to "1" $ php -d max_execution_time -r '$foo = ini_get("max_execution_time"); var_dump($foo);' string(1) "1" # Passing an empty value part will set the configuration directive to "" -d --define php -d max_execution_time= -r '$foo = ini_get("max_execution_time"); var_dump($foo);' string(0) "" # The configuration directive will be set to anything passed after the '=' character $ php -d max_execution_time=20 -r '$foo = ini_get("max_execution_time"); var_dump($foo);' string(2) "20" $ php -d max_execution_time=doesntmakesense -r '$foo = ini_get("max_execution_time"); var_dump($foo);' string(15) "doesntmakesense" -e --profile-info Activate the extended information mode, to be used by a debugger/profiler. Parse and execute the specified file. The -f is optional and may be omitted - providing just the filename to execute is sufficient. -f --file Note: To pass arguments to a script, the first argument must be --, otherwise PHP will interpret them as PHP options. -h and --help and --usage Output a list of command line options with one line descriptions of what they do. -? Calls phpinfo(), and prints out the results. If PHP is not working correctly, it is advisable -i --info to use the command php -i and see whether any error messages are printed out before or in place of the information tables. Beware that when using the CGI mode the output is in HTML and therefore very large. Provides a convenient way to perform only a syntax check on the given PHP code. On success, the text No syntax errors detected in is written to standard output and the shell return code is 0. On failure, the text Errors parsing in addition to the internal parser error message is written to standard output and the shell return code is set to -1. -l --syntax-check This option won't find fatal errors (like undefined functions). Use the -f to test for fatal errors too. Note: This option does not work together with the -r option. Example #1 Printing built in (and loaded) PHP and Zend modules $ php -m [PHP Modules] xml tokenizer standard -m --modules session posix pcre overload mysql mbstring ctype [Zend Modules] Allows execution of PHP included directly on the command line. The PHP start and end tags () are not needed and will cause a parse error if present. Note: Care must be taken when using this form of PHP not to collide with command line variable substitution done by the shell. Example #2 Getting a syntax error when using double quotes $ php -r "$foo = get_defined_constants();" PHP Parse error: syntax error, unexpected '=' in Command line code on line 1 Parse error: syntax error, unexpected '=' in Command line code on line 1 The problem here is that sh/bash performs variable substitution even when using double quotes ". Since the variable $foo is unlikely to be defined, it expands to nothing which results in the code passed to PHP for execution actually reading: $ php -r " = get_defined_constants();" The correct way would be to use single quotes '. Variables in single-quoted strings are not expanded by sh/bash. Example #3 Using single quotes to prevent the shell's variable substitution -r --run $ php -r '$foo = get_defined_constants(); var_dump($foo);' array(370) { ["E_ERROR"]=> int(1) ["E_WARNING"]=> int(2) ["E_PARSE"]=> int(4) ["E_NOTICE"]=> int(8) ["E_CORE_ERROR"]=> [...] If using a shell other than sh/bash, further issues might be experienced - if appropriate, a bug report should be opened at >> http://bugs.php.net/. It is still easy to run into trouble when trying to use variables (shell or PHP) in commnad-line code, or using backslashes for escaping, so take great care when doing so. You have been warned! Note: -r is available in the CLI SAPI, but not in the CGI SAPI. Note: This option is only intended for very basic code, so some configuration directives (such as auto_prepend_file and auto_append_file) are ignored in this mode. -B --process-begin PHP code to execute before processing stdin. Added in PHP 5. PHP code to execute for every input line. Added in PHP 5. -R --process-code There are two special variables available in this mode: $argn and $argi. $argn will contain the line PHP is processing at that moment, while $argi will contain the line number. -F --process-file PHP file to execute for every input line. Added in PHP 5. PHP code to execute after processing the input. Added in PHP 5. -E --process-end Example #4 Using the -B , -R and -E options to count the number of lines of a project. $ find my_proj | php -B '$l=0;' -R '$l += count(@file($argn));' -E 'echo "Total Lines: $l\n";' Total Lines: 37328 Display colour syntax highlighted source. This option uses the internal mechanism to parse the file and writes an HTML highlighted --syntax-highlight version of it to standard output. Note that all it does is generate a block of [...] -s and HTML tags, no HTML headers. --syntax-highlighting Note: This option does not work together with the -r option. Example #5 Using -v to get the SAPI name and the version of PHP and Zend -v --version $ php -v PHP 5.3.1 (cli) (built: Dec 11 2009 19:55:07) Copyright (c) 1997-2009 The PHP Group Zend Engine v2.3.0, Copyright (c) 1998-2009 Zend Technologies Display source with comments and whitespace stripped. -w --strip Note: This option does not work together with the -r option. Load Zend extension. If only a filename is given, PHP tries to load this extension from the current default library path on your system (usually /etc/ld.so.conf on Linux systems, for -z --zend-extension example). Passing a filename with an absolute path will not use the system's library search path. A relative filename including directory information will tell PHP to try loading the extension relative to the current directory. Show configuration file names and scanned directories. Available as of PHP 5.2.3. Example #6 --ini example --ini $ php --ini Configuration File (php.ini) Path: /usr/dev/php/5.2/lib Loaded Configuration File: /usr/dev/php/5.2/lib/php.ini Scan for additional .ini files in: (none) Additional .ini files parsed: (none) Show information about the given function or class method (e.g. number and name of the parameters). Available as of PHP 5.1.2. This option is only available if PHP was compiled with Reflection support. Example #7 basic --rf usage --rf --rfunction $ php --rf var_dump Function [ public function var_dump ] { - Parameters [2] { Parameter #0 [ $var ] Parameter #1 [ $... ] } } Show information about the given class (list of constants, properties and methods). Available as of PHP 5.1.2. This option is only available if PHP was compiled with Reflection support. Example #8 --rc example $ php --rc Directory Class [ class Directory ] { - Constants [0] { } - Static properties [0] { } --rc --rclass - Static methods [0] { } - Properties [0] { } - Methods [3] { Method [ public method close ] { } Method [ public method rewind ] { } Method [ public method read ] { } } } Show information about the given extension (list of php.ini options, defined functions, constants and classes). Available as of PHP 5.1.2. This option is only available if PHP was compiled with Reflection support. Example #9 --re example $ php --re json --re --rextension Extension [ extension #19 json version 1.2.1 ] { - Functions { Function [ function json_encode ] { } Function [ function json_decode ] { } } } --rz --rzendextension Show the configuration information for the given Zend extension (the same information that is returned by phpinfo()). Available as of PHP 5.4.0. Show the configuration information for the given extension (the same information that is returned by phpinfo()). Available as of PHP 5.2.2. The core configuration information is available using "main" as extension name. Example #10 --ri example $ php --ri date date --ri --rextinfo date/time support => enabled "Olson" Timezone Database Version => 2009.20 Timezone Database => internal Default timezone => Europe/Oslo Directive => Local Value => Master Value date.timezone => Europe/Oslo => Europe/Oslo date.default_latitude => 59.930972 => 59.930972 date.default_longitude => 10.776699 => 10.776699 date.sunset_zenith => 90.583333 => 90.583333 date.sunrise_zenith => 90.583333 => 90.583333 Note: Options -rBRFEH, --ini and --r[fcezi] are available only in CLI. ---------------------------------------------------------------------- ---------------------------------------------------------------------- Executing PHP files There are three different ways of supplying the CLI SAPI with PHP code to be executed: 1. Tell PHP to execute a certain file. $ php my_script.php $ php -f my_script.php Both ways (whether using the -f switch or not) execute the file my_script.php. Note that there is no restriction on which files can be executed; in particular, the filename is not required have a .php extension. Note: If arguments need to be passed to the script when using -f , the first argument must be --. 2. Pass the PHP code to execute directly on the command line. $ php -r 'print_r(get_defined_constants());' Special care has to be taken with regard to shell variable substitution and usage of quotes. Note: Read the example carefully: there are no beginning or ending tags! The -r switch simply does not need them, and using them will lead to a parse error. 3. Provide the PHP code to execute via standard input (stdin). This gives the powerful ability to create PHP code dynamically and feed it to the binary, as shown in this (fictional) example: $ some_application | some_filter | php | sort -u > final_output.txt You cannot combine any of the three ways to execute code. As with every shell application, the PHP binary accepts a number of arguments; however, the PHP script can also receive further arguments. The number of arguments that can be passed to your script is not limited by PHP (and although the shell has a limit to the number of characters which can be passed, this is not in general likely to be hit). The arguments passed to the script are available in the global array $argv. The first index (zero) always contains the name of the script as called from the command line. Note that, if the code is executed in-line using the command line switch -r , the value of $argv[0] will be just a dash (-). The same is true if the code is executed via a pipe from STDIN. A second global variable, $argc, contains the number of elements in the $argv array (not the number of arguments passed to the script). As long as the arguments to be passed to the script do not start with the - character, there's nothing special to watch out for. Passing an argument to the script which starts with a - will cause trouble because the PHP interpreter thinks it has to handle it itself, even before executing the script. To prevent this, use the argument list separator --. After this separator has been parsed by PHP, every following argument is passed untouched to the script. # This will not execute the given code but will show the PHP usage $ php -r 'var_dump($argv);' -h Usage: php [options] [-f] [args...] [...] # This will pass the '-h' argument to the script and prevent PHP from showing its usage $ php -r 'var_dump($argv);' -- -h array(2) { [0]=> string(1) "-" [1]=> string(2) "-h" } However, on Unix systems there's another way of using PHP for shell scripting: make the first line of the script start with #!/usr/bin/php (or whatever the path to your PHP CLI binary is if different). The rest of the file should contain normal PHP code within the usual PHP starting and end tags. Once the execution attributes of the file are set appropriately (e.g. chmod +x test), the script can be executed like any other shell or perl script: Example #1 Execute PHP script as shell script #!/usr/bin/php Assuming this file is named test in the current directory, it is now possible to do the following: $ chmod +x test $ ./test -h -- foo array(4) { [0]=> string(6) "./test" [1]=> string(2) "-h" [2]=> string(2) "--" [3]=> string(3) "foo" } As can be seen, in this case no special care needs to be taken when passing parameters starting with -. The PHP executable can be used to run PHP scripts absolutely independent of the web server. On Unix systems, the special #! (or "shebang") first line should be added to PHP scripts so that the system can automatically tell which program should run the script. On Windows platforms, it's possible to associate php.exe with the double click option of the .php extension, or a batch file can be created to run scripts through PHP. The special shebang first line for Unix does no harm on Windows (as it's formatted as a PHP comment), so cross platform programs can be written by including it. A simple example of writing a command line PHP program is shown below. Example #2 Script intended to be run from command line (script.php) #!/usr/bin/php This is a command line PHP script with one option. Usage: